Merge "Limit ComplicationHostViewController observer to attached lifecycle." into main
diff --git a/OWNERS b/OWNERS
index d0a634e..058ea36 100644
--- a/OWNERS
+++ b/OWNERS
@@ -34,6 +34,8 @@
 per-file *ravenwood* = file:ravenwood/OWNERS
 per-file *Ravenwood* = file:ravenwood/OWNERS
 
+per-file PREUPLOAD.cfg = file:/PREUPLOAD_OWNERS
+
 per-file INPUT_OWNERS = file:/INPUT_OWNERS
 per-file ZYGOTE_OWNERS = file:/ZYGOTE_OWNERS
 per-file SQLITE_OWNERS = file:/SQLITE_OWNERS
@@ -48,3 +50,4 @@
 per-file ADPF_OWNERS = file:/ADPF_OWNERS
 per-file GAME_MANAGER_OWNERS = file:/GAME_MANAGER_OWNERS
 per-file SDK_OWNERS = file:/SDK_OWNERS
+per-file PREUPLOAD_OWNERS = file:/PREUPLOAD_OWNERS
diff --git a/PREUPLOAD_OWNERS b/PREUPLOAD_OWNERS
new file mode 100644
index 0000000..ece4d3e
--- /dev/null
+++ b/PREUPLOAD_OWNERS
@@ -0,0 +1,2 @@
+roosa@google.com
+gsennton@google.com
diff --git a/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java b/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java
index ed669be..c775280 100644
--- a/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java
@@ -63,14 +63,12 @@
 
     @Test
     @Parameters(method = "getData")
-    public void timeZipFileOpen(int numEntries) throws Exception {
+    public void timeZipFileOpenClose(int numEntries) throws Exception {
         setUp(numEntries);
         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         while (state.keepRunning()) {
             ZipFile zf = new ZipFile(mFile);
-            state.pauseTiming();
             zf.close();
-            state.resumeTiming();
         }
     }
 
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 fe80d1b..8fad79a 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -5926,9 +5926,6 @@
             pw.print(Flags.FLAG_DO_NOT_FORCE_RUSH_EXECUTION_AT_BOOT,
                     Flags.doNotForceRushExecutionAtBoot());
             pw.println();
-            pw.print(android.app.job.Flags.FLAG_BACKUP_JOBS_EXEMPTION,
-                    android.app.job.Flags.backupJobsExemption());
-            pw.println();
             pw.print(android.app.job.Flags.FLAG_IGNORE_IMPORTANT_WHILE_FOREGROUND,
                     android.app.job.Flags.ignoreImportantWhileForeground());
             pw.println();
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
index f3bc9c7..42c8250 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
@@ -433,9 +433,6 @@
             case com.android.server.job.Flags.FLAG_DO_NOT_FORCE_RUSH_EXECUTION_AT_BOOT:
                 pw.println(com.android.server.job.Flags.doNotForceRushExecutionAtBoot());
                 break;
-            case android.app.job.Flags.FLAG_BACKUP_JOBS_EXEMPTION:
-                pw.println(android.app.job.Flags.backupJobsExemption());
-                break;
             case android.app.job.Flags.FLAG_IGNORE_IMPORTANT_WHILE_FOREGROUND:
                 pw.println(android.app.job.Flags.ignoreImportantWhileForeground());
                 break;
diff --git a/api/ApiDocs.bp b/api/ApiDocs.bp
index 89351fd..03fb44f 100644
--- a/api/ApiDocs.bp
+++ b/api/ApiDocs.bp
@@ -130,6 +130,10 @@
 droidstubs {
     name: "framework-doc-stubs",
     defaults: ["android-non-updatable-doc-stubs-defaults"],
+    flags: [
+        // Ignore any compatibility errors, see check_api.last_released below for more information.
+        "--hide-category Compatibility",
+    ],
     srcs: [":all-modules-public-stubs-source-exportable"],
     api_levels_module: "api_versions_public",
     aidl: {
@@ -138,13 +142,39 @@
             "packages/modules/Media/apex/aidl/stable",
         ],
     },
+
+    // Pass the previously released API to support reverting flagged APIs. Without this, reverting
+    // a flagged API will cause it to be removed, even if it had previously been released. This
+    // has the side effect of causing compatibility issues to be reported but they are already
+    // checked elsewhere so they will be ignored, see `--hide-category Compatibility` above.
+    check_api: {
+        last_released: {
+            api_file: ":android.api.combined.public.latest",
+            removed_api_file: ":android-removed.api.combined.public.latest",
+        },
+    },
 }
 
 droidstubs {
     name: "framework-doc-system-stubs",
     defaults: ["framework-doc-stubs-sources-default"],
-    flags: ["--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\)"],
+    flags: [
+        "--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\)",
+        // Ignore any compatibility errors, see check_api.last_released below for more information.
+        "--hide-category Compatibility",
+    ],
     api_levels_module: "api_versions_system",
+
+    // Pass the previously released API to support reverting flagged APIs. Without this, reverting
+    // a flagged API will cause it to be removed, even if it had previously been released. This
+    // has the side effect of causing compatibility issues to be reported but they are already
+    // checked elsewhere so they will be ignored, see `--hide-category Compatibility` above.
+    check_api: {
+        last_released: {
+            api_file: ":android.api.combined.system.latest",
+            removed_api_file: ":android-removed.api.combined.system.latest",
+        },
+    },
 }
 
 /////////////////////////////////////////////////////////////////////
diff --git a/boot/preloaded-classes b/boot/preloaded-classes
index a696e03..afd9984 100644
--- a/boot/preloaded-classes
+++ b/boot/preloaded-classes
@@ -6469,6 +6469,7 @@
 android.os.connectivity.WifiActivityEnergyInfo
 android.os.connectivity.WifiBatteryStats$1
 android.os.connectivity.WifiBatteryStats
+android.os.flagging.AconfigPackage
 android.os.health.HealthKeys$Constant
 android.os.health.HealthKeys$Constants
 android.os.health.HealthKeys$SortedIntArray
diff --git a/config/preloaded-classes b/config/preloaded-classes
index ed40276..343de0b 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -6473,6 +6473,7 @@
 android.os.connectivity.WifiActivityEnergyInfo
 android.os.connectivity.WifiBatteryStats$1
 android.os.connectivity.WifiBatteryStats
+android.os.flagging.AconfigPackage
 android.os.health.HealthKeys$Constant
 android.os.health.HealthKeys$Constants
 android.os.health.HealthKeys$SortedIntArray
diff --git a/core/api/current.txt b/core/api/current.txt
index 30323c0..e2f57c2 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -280,6 +280,7 @@
     field public static final String REQUEST_COMPANION_PROFILE_COMPUTER = "android.permission.REQUEST_COMPANION_PROFILE_COMPUTER";
     field public static final String REQUEST_COMPANION_PROFILE_GLASSES = "android.permission.REQUEST_COMPANION_PROFILE_GLASSES";
     field public static final String REQUEST_COMPANION_PROFILE_NEARBY_DEVICE_STREAMING = "android.permission.REQUEST_COMPANION_PROFILE_NEARBY_DEVICE_STREAMING";
+    field @FlaggedApi("android.companion.virtualdevice.flags.enable_limited_vdm_role") public static final String REQUEST_COMPANION_PROFILE_SENSOR_DEVICE_STREAMING = "android.permission.REQUEST_COMPANION_PROFILE_SENSOR_DEVICE_STREAMING";
     field public static final String REQUEST_COMPANION_PROFILE_WATCH = "android.permission.REQUEST_COMPANION_PROFILE_WATCH";
     field public static final String REQUEST_COMPANION_RUN_IN_BACKGROUND = "android.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND";
     field public static final String REQUEST_COMPANION_SELF_MANAGED = "android.permission.REQUEST_COMPANION_SELF_MANAGED";
@@ -10065,6 +10066,7 @@
     field @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_PROFILE_COMPUTER) public static final String DEVICE_PROFILE_COMPUTER = "android.app.role.COMPANION_DEVICE_COMPUTER";
     field @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_PROFILE_GLASSES) public static final String DEVICE_PROFILE_GLASSES = "android.app.role.COMPANION_DEVICE_GLASSES";
     field @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_PROFILE_NEARBY_DEVICE_STREAMING) public static final String DEVICE_PROFILE_NEARBY_DEVICE_STREAMING = "android.app.role.COMPANION_DEVICE_NEARBY_DEVICE_STREAMING";
+    field @FlaggedApi("android.companion.virtualdevice.flags.enable_limited_vdm_role") @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_PROFILE_SENSOR_DEVICE_STREAMING) public static final String DEVICE_PROFILE_SENSOR_DEVICE_STREAMING = "android.app.role.COMPANION_DEVICE_SENSOR_DEVICE_STREAMING";
     field public static final String DEVICE_PROFILE_WATCH = "android.app.role.COMPANION_DEVICE_WATCH";
   }
 
@@ -13380,6 +13382,7 @@
     method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedDrawableForDensity(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle, @Nullable android.graphics.Rect, int);
     method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedIcon(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle);
     method @NonNull public abstract CharSequence getUserBadgedLabel(@NonNull CharSequence, @NonNull android.os.UserHandle);
+    method @FlaggedApi("android.content.pm.cloud_compilation_pm") @NonNull public static android.content.pm.SigningInfo getVerifiedSigningInfo(@NonNull String, int) throws android.content.pm.SigningInfoException;
     method @NonNull @RequiresPermission(value="android.permission.WHITELIST_RESTRICTED_PERMISSIONS", conditional=true) public java.util.Set<java.lang.String> getWhitelistedRestrictedPermissions(@NonNull String, int);
     method @Nullable public abstract android.content.res.XmlResourceParser getXml(@NonNull String, @XmlRes int, @Nullable android.content.pm.ApplicationInfo);
     method public boolean hasSigningCertificate(@NonNull String, @NonNull byte[], int);
@@ -14025,8 +14028,17 @@
     method public android.content.pm.Signature[] getSigningCertificateHistory();
     method public boolean hasMultipleSigners();
     method public boolean hasPastSigningCertificates();
+    method @FlaggedApi("android.content.pm.cloud_compilation_pm") public boolean signersMatchExactly(@NonNull android.content.pm.SigningInfo);
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.SigningInfo> CREATOR;
+    field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_JAR = 1; // 0x1
+    field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V2 = 2; // 0x2
+    field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V3 = 3; // 0x3
+    field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V4 = 4; // 0x4
+  }
+
+  @FlaggedApi("android.content.pm.cloud_compilation_pm") public class SigningInfoException extends java.lang.Exception {
+    method @FlaggedApi("android.content.pm.cloud_compilation_pm") public int getCode();
   }
 
   public final class VersionedPackage implements android.os.Parcelable {
@@ -29956,7 +29968,7 @@
   public class X509TrustManagerExtensions {
     ctor public X509TrustManagerExtensions(javax.net.ssl.X509TrustManager) throws java.lang.IllegalArgumentException;
     method public java.util.List<java.security.cert.X509Certificate> checkServerTrusted(java.security.cert.X509Certificate[], String, String) throws java.security.cert.CertificateException;
-    method @FlaggedApi("android.net.platform.flags.x509_extensions_certificate_transparency") @NonNull public java.util.List<java.security.cert.X509Certificate> checkServerTrusted(@NonNull java.security.cert.X509Certificate[], @Nullable byte[], @Nullable byte[], @NonNull String, @NonNull String) throws java.security.cert.CertificateException;
+    method @FlaggedApi("android.security.certificate_transparency_configuration") @NonNull public java.util.List<java.security.cert.X509Certificate> checkServerTrusted(@NonNull java.security.cert.X509Certificate[], @Nullable byte[], @Nullable byte[], @NonNull String, @NonNull String) throws java.security.cert.CertificateException;
     method public boolean isSameTrustConfiguration(String, String);
     method public boolean isUserAddedCertificate(java.security.cert.X509Certificate);
   }
@@ -34765,9 +34777,10 @@
     method public android.os.MessageQueue getMessageQueue();
     method public boolean hasMessages(android.os.Handler, Object, int);
     method public boolean hasMessages(android.os.Handler, Object, Runnable);
+    method @FlaggedApi("android.os.message_queue_testability") public boolean isBlockedOnSyncBarrier();
     method public android.os.Message next();
     method @FlaggedApi("android.os.message_queue_testability") @Nullable public Long peekWhen();
-    method @FlaggedApi("android.os.message_queue_testability") @Nullable public android.os.Message pop();
+    method @FlaggedApi("android.os.message_queue_testability") @Nullable public android.os.Message poll();
     method public void recycle(android.os.Message);
     method public void release();
   }
@@ -44887,11 +44900,11 @@
     field public static final String KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY = "carrier_vvm_package_name_string_array";
     field public static final String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool";
     field public static final String KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL = "carrier_wfc_supports_wifi_only_bool";
-    field public static final String KEY_CDMA_3WAYCALL_FLASH_DELAY_INT = "cdma_3waycall_flash_delay_int";
-    field public static final String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
-    field public static final String KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
-    field public static final String KEY_CDMA_ROAMING_MODE_INT = "cdma_roaming_mode_int";
-    field public static final String KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array";
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_CDMA_3WAYCALL_FLASH_DELAY_INT = "cdma_3waycall_flash_delay_int";
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_CDMA_ROAMING_MODE_INT = "cdma_roaming_mode_int";
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array";
     field public static final String KEY_CELLULAR_SERVICE_CAPABILITIES_INT_ARRAY = "cellular_service_capabilities_int_array";
     field public static final String KEY_CELLULAR_USAGE_SETTING_INT = "cellular_usage_setting_int";
     field public static final String KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL = "check_pricing_with_carrier_data_roaming_bool";
@@ -44918,7 +44931,7 @@
     field public static final String KEY_DEFAULT_VM_NUMBER_ROAMING_AND_IMS_UNREGISTERED_STRING = "default_vm_number_roaming_and_ims_unregistered_string";
     field public static final String KEY_DEFAULT_VM_NUMBER_STRING = "default_vm_number_string";
     field public static final String KEY_DIAL_STRING_REPLACE_STRING_ARRAY = "dial_string_replace_string_array";
-    field public static final String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
     field public static final String KEY_DISABLE_CHARGE_INDICATION_BOOL = "disable_charge_indication_bool";
     field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_DISABLE_DUN_APN_WHILE_ROAMING_WITH_PRESET_APN_BOOL = "disable_dun_apn_while_roaming_with_preset_apn_bool";
     field public static final String KEY_DISABLE_SUPPLEMENTARY_SERVICES_IN_AIRPLANE_MODE_BOOL = "disable_supplementary_services_in_airplane_mode_bool";
@@ -45058,6 +45071,7 @@
     field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_ENTITLEMENT_STATUS_REFRESH_DAYS_INT = "satellite_entitlement_status_refresh_days_int";
     field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL = "satellite_entitlement_supported_bool";
     field @FlaggedApi("com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn") public static final String KEY_SATELLITE_ESOS_SUPPORTED_BOOL = "satellite_esos_supported_bool";
+    field @FlaggedApi("com.android.internal.telephony.flags.satellite_25q4_apis") public static final String KEY_SATELLITE_IGNORE_DATA_ROAMING_SETTING_BOOL = "satellite_ignore_data_roaming_setting_bool";
     field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_SATELLITE_INFORMATION_REDIRECT_URL_STRING = "satellite_information_redirect_url_string";
     field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_SATELLITE_NIDD_APN_NAME_STRING = "satellite_nidd_apn_name_string";
     field @FlaggedApi("com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn") public static final String KEY_SATELLITE_ROAMING_ESOS_INACTIVITY_TIMEOUT_SEC_INT = "satellite_roaming_esos_inactivity_timeout_sec_int";
@@ -45069,10 +45083,10 @@
     field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_SATELLITE_SUPPORTED_MSG_APPS_STRING_ARRAY = "satellite_supported_msg_apps_string_array";
     field public static final String KEY_SHOW_4G_FOR_3G_DATA_ICON_BOOL = "show_4g_for_3g_data_icon_bool";
     field public static final String KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL = "show_4g_for_lte_data_icon_bool";
-    field public static final String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
     field public static final String KEY_SHOW_BLOCKING_PAY_PHONE_OPTION_BOOL = "show_blocking_pay_phone_option_bool";
     field public static final String KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL = "show_call_blocking_disabled_notification_always_bool";
-    field public static final String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool";
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool";
     field public static final String KEY_SHOW_FORWARDED_NUMBER_BOOL = "show_forwarded_number_bool";
     field public static final String KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL = "show_iccid_in_sim_status_bool";
     field public static final String KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL = "show_ims_registration_status_bool";
@@ -45102,7 +45116,7 @@
     field public static final String KEY_SUPPORT_ENHANCED_CALL_BLOCKING_BOOL = "support_enhanced_call_blocking_bool";
     field public static final String KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_BOOL = "support_ims_conference_event_package_bool";
     field public static final String KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL = "support_pause_ims_video_calls_bool";
-    field public static final String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
     field public static final String KEY_SUPPORT_TDSCDMA_BOOL = "support_tdscdma_bool";
     field public static final String KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY = "support_tdscdma_roaming_networks_string_array";
     field public static final String KEY_SWITCH_DATA_TO_PRIMARY_IF_PRIMARY_IS_OOS_BOOL = "switch_data_to_primary_if_primary_is_oos_bool";
@@ -45112,7 +45126,7 @@
     field public static final String KEY_USE_ACS_FOR_RCS_BOOL = "use_acs_for_rcs_bool";
     field public static final String KEY_USE_HFA_FOR_PROVISIONING_BOOL = "use_hfa_for_provisioning_bool";
     field public static final String KEY_USE_IP_FOR_CALLING_INDICATOR_BOOL = "use_ip_for_calling_indicator_bool";
-    field public static final String KEY_USE_OTASP_FOR_PROVISIONING_BOOL = "use_otasp_for_provisioning_bool";
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_USE_OTASP_FOR_PROVISIONING_BOOL = "use_otasp_for_provisioning_bool";
     field @Deprecated public static final String KEY_USE_RCS_PRESENCE_BOOL = "use_rcs_presence_bool";
     field public static final String KEY_USE_RCS_SIP_OPTIONS_BOOL = "use_rcs_sip_options_bool";
     field public static final String KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL = "use_wfc_home_network_mode_in_roaming_network_bool";
@@ -45548,13 +45562,13 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentity> CREATOR;
   }
 
-  public final class CellIdentityCdma extends android.telephony.CellIdentity {
-    method public int getBasestationId();
-    method public int getLatitude();
-    method public int getLongitude();
-    method public int getNetworkId();
-    method public int getSystemId();
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityCdma> CREATOR;
+  @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public final class CellIdentityCdma extends android.telephony.CellIdentity {
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getBasestationId();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getLatitude();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getLongitude();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getNetworkId();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getSystemId();
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityCdma> CREATOR;
   }
 
   public final class CellIdentityGsm extends android.telephony.CellIdentity {
@@ -45646,11 +45660,11 @@
     field public static final long UNAVAILABLE_LONG = 9223372036854775807L; // 0x7fffffffffffffffL
   }
 
-  public final class CellInfoCdma extends android.telephony.CellInfo implements android.os.Parcelable {
-    method @NonNull public android.telephony.CellIdentityCdma getCellIdentity();
-    method @NonNull public android.telephony.CellSignalStrengthCdma getCellSignalStrength();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellInfoCdma> CREATOR;
+  @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public final class CellInfoCdma extends android.telephony.CellInfo implements android.os.Parcelable {
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public android.telephony.CellIdentityCdma getCellIdentity();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public android.telephony.CellSignalStrengthCdma getCellSignalStrength();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public void writeToParcel(android.os.Parcel, int);
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellInfoCdma> CREATOR;
   }
 
   public final class CellInfoGsm extends android.telephony.CellInfo implements android.os.Parcelable {
@@ -47229,11 +47243,11 @@
     method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getImei(int);
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.READ_SMS, android.Manifest.permission.READ_PHONE_NUMBERS}) public String getLine1Number();
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public String getManualNetworkSelectionPlmn();
-    method @Nullable public String getManufacturerCode();
-    method @Nullable public String getManufacturerCode(int);
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @Nullable public String getManufacturerCode();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @Nullable public String getManufacturerCode(int);
     method public static long getMaximumCallComposerPictureSize();
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getMeid();
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getMeid(int);
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getMeid();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getMeid(int);
     method public String getMmsUAProfUrl();
     method public String getMmsUserAgent();
     method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getNai();
@@ -47379,10 +47393,10 @@
     field public static final int CARRIER_RESTRICTION_STATUS_RESTRICTED = 2; // 0x2
     field public static final int CARRIER_RESTRICTION_STATUS_RESTRICTED_TO_CALLER = 3; // 0x3
     field public static final int CARRIER_RESTRICTION_STATUS_UNKNOWN = 0; // 0x0
-    field public static final int CDMA_ROAMING_MODE_AFFILIATED = 1; // 0x1
-    field public static final int CDMA_ROAMING_MODE_ANY = 2; // 0x2
-    field public static final int CDMA_ROAMING_MODE_HOME = 0; // 0x0
-    field public static final int CDMA_ROAMING_MODE_RADIO_DEFAULT = -1; // 0xffffffff
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ROAMING_MODE_AFFILIATED = 1; // 0x1
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ROAMING_MODE_ANY = 2; // 0x2
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ROAMING_MODE_HOME = 0; // 0x0
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ROAMING_MODE_RADIO_DEFAULT = -1; // 0xffffffff
     field public static final int DATA_ACTIVITY_DORMANT = 4; // 0x4
     field public static final int DATA_ACTIVITY_IN = 1; // 0x1
     field public static final int DATA_ACTIVITY_INOUT = 3; // 0x3
@@ -47402,9 +47416,9 @@
     field public static final int DATA_SUSPENDED = 3; // 0x3
     field public static final int DATA_UNKNOWN = -1; // 0xffffffff
     field public static final int DEFAULT_PORT_INDEX = 0; // 0x0
-    field public static final int ERI_FLASH = 2; // 0x2
-    field public static final int ERI_OFF = 1; // 0x1
-    field public static final int ERI_ON = 0; // 0x0
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int ERI_FLASH = 2; // 0x2
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int ERI_OFF = 1; // 0x1
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int ERI_ON = 0; // 0x0
     field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final String EVENT_DISPLAY_EMERGENCY_MESSAGE = "android.telephony.event.DISPLAY_EMERGENCY_MESSAGE";
     field public static final String EXTRA_ACTIVE_SIM_SUPPORTED_COUNT = "android.telephony.extra.ACTIVE_SIM_SUPPORTED_COUNT";
     field public static final String EXTRA_APN_PROTOCOL = "android.telephony.extra.APN_PROTOCOL";
@@ -47445,11 +47459,11 @@
     field public static final int NETWORK_SELECTION_MODE_AUTO = 1; // 0x1
     field public static final int NETWORK_SELECTION_MODE_MANUAL = 2; // 0x2
     field public static final int NETWORK_SELECTION_MODE_UNKNOWN = 0; // 0x0
-    field public static final int NETWORK_TYPE_1xRTT = 7; // 0x7
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_1xRTT = 7; // 0x7
     field public static final long NETWORK_TYPE_BITMASK_1xRTT = 64L; // 0x40L
-    field public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L
     field public static final long NETWORK_TYPE_BITMASK_EDGE = 2L; // 0x2L
-    field public static final long NETWORK_TYPE_BITMASK_EHRPD = 8192L; // 0x2000L
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final long NETWORK_TYPE_BITMASK_EHRPD = 8192L; // 0x2000L
     field public static final long NETWORK_TYPE_BITMASK_EVDO_0 = 16L; // 0x10L
     field public static final long NETWORK_TYPE_BITMASK_EVDO_A = 32L; // 0x20L
     field public static final long NETWORK_TYPE_BITMASK_EVDO_B = 2048L; // 0x800L
@@ -47462,17 +47476,16 @@
     field public static final long NETWORK_TYPE_BITMASK_IWLAN = 131072L; // 0x20000L
     field public static final long NETWORK_TYPE_BITMASK_LTE = 4096L; // 0x1000L
     field @Deprecated public static final long NETWORK_TYPE_BITMASK_LTE_CA = 262144L; // 0x40000L
-    field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final long NETWORK_TYPE_BITMASK_NB_IOT_NTN = 1048576L; // 0x100000L
     field public static final long NETWORK_TYPE_BITMASK_NR = 524288L; // 0x80000L
     field public static final long NETWORK_TYPE_BITMASK_TD_SCDMA = 65536L; // 0x10000L
     field public static final long NETWORK_TYPE_BITMASK_UMTS = 4L; // 0x4L
     field public static final long NETWORK_TYPE_BITMASK_UNKNOWN = 0L; // 0x0L
-    field public static final int NETWORK_TYPE_CDMA = 4; // 0x4
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_CDMA = 4; // 0x4
     field public static final int NETWORK_TYPE_EDGE = 2; // 0x2
-    field public static final int NETWORK_TYPE_EHRPD = 14; // 0xe
-    field public static final int NETWORK_TYPE_EVDO_0 = 5; // 0x5
-    field public static final int NETWORK_TYPE_EVDO_A = 6; // 0x6
-    field public static final int NETWORK_TYPE_EVDO_B = 12; // 0xc
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_EHRPD = 14; // 0xe
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_EVDO_0 = 5; // 0x5
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_EVDO_A = 6; // 0x6
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_EVDO_B = 12; // 0xc
     field public static final int NETWORK_TYPE_GPRS = 1; // 0x1
     field public static final int NETWORK_TYPE_GSM = 16; // 0x10
     field public static final int NETWORK_TYPE_HSDPA = 8; // 0x8
@@ -47482,12 +47495,11 @@
     field @Deprecated public static final int NETWORK_TYPE_IDEN = 11; // 0xb
     field public static final int NETWORK_TYPE_IWLAN = 18; // 0x12
     field public static final int NETWORK_TYPE_LTE = 13; // 0xd
-    field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final int NETWORK_TYPE_NB_IOT_NTN = 21; // 0x15
     field public static final int NETWORK_TYPE_NR = 20; // 0x14
     field public static final int NETWORK_TYPE_TD_SCDMA = 17; // 0x11
     field public static final int NETWORK_TYPE_UMTS = 3; // 0x3
     field public static final int NETWORK_TYPE_UNKNOWN = 0; // 0x0
-    field public static final int PHONE_TYPE_CDMA = 2; // 0x2
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int PHONE_TYPE_CDMA = 2; // 0x2
     field public static final int PHONE_TYPE_GSM = 1; // 0x1
     field public static final int PHONE_TYPE_NONE = 0; // 0x0
     field public static final int PHONE_TYPE_SIP = 3; // 0x3
@@ -49355,7 +49367,7 @@
     method public static void dumpSpans(CharSequence, android.util.Printer, String);
     method public static CharSequence ellipsize(CharSequence, android.text.TextPaint, float, android.text.TextUtils.TruncateAt);
     method public static CharSequence ellipsize(CharSequence, android.text.TextPaint, float, android.text.TextUtils.TruncateAt, boolean, @Nullable android.text.TextUtils.EllipsizeCallback);
-    method public static boolean equals(CharSequence, CharSequence);
+    method public static boolean equals(@Nullable CharSequence, @Nullable CharSequence);
     method public static CharSequence expandTemplate(CharSequence, java.lang.CharSequence...);
     method public static int getCapsMode(CharSequence, int, int);
     method public static void getChars(CharSequence, int, int, char[], int);
@@ -58365,6 +58377,7 @@
     method @NonNull @WorkerThread public default android.view.textclassifier.TextSelection suggestSelection(@NonNull android.view.textclassifier.TextSelection.Request);
     method @NonNull @WorkerThread public default android.view.textclassifier.TextSelection suggestSelection(@NonNull CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @Nullable android.os.LocaleList);
     field public static final String EXTRA_FROM_TEXT_CLASSIFIER = "android.view.textclassifier.extra.FROM_TEXT_CLASSIFIER";
+    field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final String EXTRA_TEXT_ORIGIN_PACKAGE = "android.view.textclassifier.extra.TEXT_ORIGIN_PACKAGE";
     field public static final String HINT_TEXT_IS_EDITABLE = "android.text_is_editable";
     field public static final String HINT_TEXT_IS_NOT_EDITABLE = "android.text_is_not_editable";
     field public static final android.view.textclassifier.TextClassifier NO_OP;
@@ -58374,6 +58387,7 @@
     field public static final String TYPE_EMAIL = "email";
     field public static final String TYPE_FLIGHT_NUMBER = "flight";
     field public static final String TYPE_OTHER = "other";
+    field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final String TYPE_OTP = "otp";
     field public static final String TYPE_PHONE = "phone";
     field public static final String TYPE_UNKNOWN = "";
     field public static final String TYPE_URL = "url";
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index bca2ce2..40069aa 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -130,7 +130,6 @@
 
   public abstract class PackageManager {
     method @NonNull public String getSdkSandboxPackageName();
-    method @FlaggedApi("android.content.pm.cloud_compilation_pm") @NonNull public static android.content.pm.SigningInfo getVerifiedSigningInfo(@NonNull String, int) throws android.content.pm.SigningInfoException;
     method @RequiresPermission(android.Manifest.permission.MAKE_UID_VISIBLE) public void makeUidVisible(int, int);
     field public static final String EXTRA_VERIFICATION_ROOT_HASH = "android.content.pm.extra.VERIFICATION_ROOT_HASH";
     field public static final int MATCH_STATIC_SHARED_AND_SDK_LIBRARIES = 67108864; // 0x4000000
@@ -141,18 +140,6 @@
     method @NonNull public String getPackageName();
   }
 
-  public final class SigningInfo implements android.os.Parcelable {
-    method @FlaggedApi("android.content.pm.cloud_compilation_pm") public boolean signersMatchExactly(@NonNull android.content.pm.SigningInfo);
-    field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_JAR = 1; // 0x1
-    field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V2 = 2; // 0x2
-    field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V3 = 3; // 0x3
-    field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V4 = 4; // 0x4
-  }
-
-  @FlaggedApi("android.content.pm.cloud_compilation_pm") public class SigningInfoException extends java.lang.Exception {
-    method @FlaggedApi("android.content.pm.cloud_compilation_pm") public int getCode();
-  }
-
 }
 
 package android.hardware.usb {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 4a4776d..f2643b1 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -10,6 +10,7 @@
     field @FlaggedApi("android.app.contextualsearch.flags.enable_service") public static final String ACCESS_CONTEXTUAL_SEARCH = "android.permission.ACCESS_CONTEXTUAL_SEARCH";
     field public static final String ACCESS_CONTEXT_HUB = "android.permission.ACCESS_CONTEXT_HUB";
     field public static final String ACCESS_DRM_CERTIFICATES = "android.permission.ACCESS_DRM_CERTIFICATES";
+    field @FlaggedApi("android.permission.flags.fine_power_monitor_permission") public static final String ACCESS_FINE_POWER_MONITORS = "android.permission.ACCESS_FINE_POWER_MONITORS";
     field @Deprecated public static final String ACCESS_FM_RADIO = "android.permission.ACCESS_FM_RADIO";
     field public static final String ACCESS_FPS_COUNTER = "android.permission.ACCESS_FPS_COUNTER";
     field @FlaggedApi("android.multiuser.enable_permission_to_access_hidden_profiles") public static final String ACCESS_HIDDEN_PROFILES_FULL = "android.permission.ACCESS_HIDDEN_PROFILES_FULL";
@@ -26,6 +27,7 @@
     field public static final String ACCESS_SHORTCUTS = "android.permission.ACCESS_SHORTCUTS";
     field @FlaggedApi("android.app.smartspace.flags.access_smartspace") public static final String ACCESS_SMARTSPACE = "android.permission.ACCESS_SMARTSPACE";
     field public static final String ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER";
+    field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final String ACCESS_TEXT_CLASSIFIER_BY_TYPE = "android.permission.ACCESS_TEXT_CLASSIFIER_BY_TYPE";
     field public static final String ACCESS_TUNED_INFO = "android.permission.ACCESS_TUNED_INFO";
     field public static final String ACCESS_TV_DESCRAMBLER = "android.permission.ACCESS_TV_DESCRAMBLER";
     field public static final String ACCESS_TV_SHARED_FILTER = "android.permission.ACCESS_TV_SHARED_FILTER";
@@ -518,6 +520,9 @@
     field public static final int config_defaultCallScreening = 17039398; // 0x1040026
     field public static final int config_defaultDialer = 17039395; // 0x1040023
     field public static final int config_defaultNotes = 17039429; // 0x1040045
+    field @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence_module") public static final int config_defaultOnDeviceIntelligenceDeviceConfigNamespace;
+    field @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence_module") public static final int config_defaultOnDeviceIntelligenceService;
+    field @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence_module") public static final int config_defaultOnDeviceSandboxedInferenceService;
     field @FlaggedApi("android.permission.flags.cross_user_role_platform_api_enabled") public static final int config_defaultReservedForTestingProfileGroupExclusivity;
     field @FlaggedApi("android.permission.flags.retail_demo_role_enabled") public static final int config_defaultRetailDemo = 17039432; // 0x1040048
     field public static final int config_defaultSms = 17039396; // 0x1040024
@@ -5086,6 +5091,7 @@
     field public static final int REASON_ENDPOINT_STOPPED = 6; // 0x6
     field public static final int REASON_FAILURE = 0; // 0x0
     field public static final int REASON_OPEN_ENDPOINT_SESSION_REQUEST_REJECTED = 3; // 0x3
+    field public static final int REASON_PERMISSION_DENIED = 9; // 0x9
   }
 
   public static final class HubEndpoint.Builder {
@@ -12711,14 +12717,14 @@
   }
 
   @FlaggedApi("android.security.secure_lockdown") public final class DisableSecureLockDeviceParams implements android.os.Parcelable {
-    ctor public DisableSecureLockDeviceParams(@NonNull String);
+    ctor public DisableSecureLockDeviceParams(@NonNull CharSequence);
     method public int describeContents();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.security.authenticationpolicy.DisableSecureLockDeviceParams> CREATOR;
   }
 
   @FlaggedApi("android.security.secure_lockdown") public final class EnableSecureLockDeviceParams implements android.os.Parcelable {
-    ctor public EnableSecureLockDeviceParams(@NonNull String);
+    ctor public EnableSecureLockDeviceParams(@NonNull CharSequence);
     method public int describeContents();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.security.authenticationpolicy.EnableSecureLockDeviceParams> CREATOR;
@@ -14630,7 +14636,7 @@
     field public static final int CALLTYPE_INCOMING = 1; // 0x1
     field public static final int CALLTYPE_OUTGOING = 2; // 0x2
     field public static final int CALLTYPE_UNKNOWN = 0; // 0x0
-    field public static final int CDMA_PHONE = 1; // 0x1
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_PHONE = 1; // 0x1
     field @NonNull public static final android.os.Parcelable.Creator<android.telecom.ParcelableCallAnalytics> CREATOR;
     field public static final int GSM_PHONE = 2; // 0x2
     field public static final int IMS_PHONE = 4; // 0x4
@@ -15011,7 +15017,7 @@
     field public static final String KEY_GBA_UA_SECURITY_ORGANIZATION_INT = "gba_ua_security_organization_int";
     field public static final String KEY_GBA_UA_SECURITY_PROTOCOL_INT = "gba_ua_security_protocol_int";
     field public static final String KEY_GBA_UA_TLS_CIPHER_SUITE_INT = "gba_ua_tls_cipher_suite_int";
-    field public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool";
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool";
   }
 
   public static final class CarrierConfigManager.Wifi {
@@ -15098,8 +15104,8 @@
     ctor public CellBroadcastService();
     method @NonNull @WorkerThread public abstract CharSequence getCellBroadcastAreaInfo(int);
     method @CallSuper public android.os.IBinder onBind(@Nullable android.content.Intent);
-    method public abstract void onCdmaCellBroadcastSms(int, @NonNull byte[], int);
-    method public abstract void onCdmaScpMessage(int, @NonNull java.util.List<android.telephony.cdma.CdmaSmsCbProgramData>, @NonNull String, @NonNull java.util.function.Consumer<android.os.Bundle>);
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public void onCdmaCellBroadcastSms(int, @NonNull byte[], int);
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public void onCdmaScpMessage(int, @NonNull java.util.List<android.telephony.cdma.CdmaSmsCbProgramData>, @NonNull String, @NonNull java.util.function.Consumer<android.os.Bundle>);
     method public abstract void onGsmCellBroadcastSms(int, @NonNull byte[]);
     field public static final String CELL_BROADCAST_SERVICE_INTERFACE = "android.telephony.CellBroadcastService";
   }
@@ -15109,9 +15115,9 @@
     method @NonNull public abstract android.telephony.CellIdentity sanitizeLocationInfo();
   }
 
-  public final class CellIdentityCdma extends android.telephony.CellIdentity {
-    method @NonNull public android.telephony.cdma.CdmaCellLocation asCellLocation();
-    method @NonNull public android.telephony.CellIdentityCdma sanitizeLocationInfo();
+  @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public final class CellIdentityCdma extends android.telephony.CellIdentity {
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public android.telephony.cdma.CdmaCellLocation asCellLocation();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public android.telephony.CellIdentityCdma sanitizeLocationInfo();
   }
 
   public final class CellIdentityGsm extends android.telephony.CellIdentity {
@@ -15527,16 +15533,16 @@
     field public static final int BUSY = 17; // 0x11
     field public static final int CALL_BARRED = 240; // 0xf0
     field public static final int CALL_REJECTED = 21; // 0x15
-    field public static final int CDMA_ACCESS_BLOCKED = 1009; // 0x3f1
-    field public static final int CDMA_ACCESS_FAILURE = 1006; // 0x3ee
-    field public static final int CDMA_DROP = 1001; // 0x3e9
-    field public static final int CDMA_INTERCEPT = 1002; // 0x3ea
-    field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000; // 0x3e8
-    field public static final int CDMA_NOT_EMERGENCY = 1008; // 0x3f0
-    field public static final int CDMA_PREEMPTED = 1007; // 0x3ef
-    field public static final int CDMA_REORDER = 1003; // 0x3eb
-    field public static final int CDMA_RETRY_ORDER = 1005; // 0x3ed
-    field public static final int CDMA_SO_REJECT = 1004; // 0x3ec
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ACCESS_BLOCKED = 1009; // 0x3f1
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ACCESS_FAILURE = 1006; // 0x3ee
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_DROP = 1001; // 0x3e9
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_INTERCEPT = 1002; // 0x3ea
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000; // 0x3e8
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_NOT_EMERGENCY = 1008; // 0x3f0
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_PREEMPTED = 1007; // 0x3ef
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_REORDER = 1003; // 0x3eb
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_RETRY_ORDER = 1005; // 0x3ed
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_SO_REJECT = 1004; // 0x3ec
     field public static final int CHANNEL_NOT_AVAIL = 44; // 0x2c
     field public static final int CHANNEL_UNACCEPTABLE = 6; // 0x6
     field public static final int CONDITIONAL_IE_ERROR = 100; // 0x64
@@ -16070,14 +16076,14 @@
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierRestrictionRules getCarrierRestrictionRules();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getCarrierServicePackageName();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getCarrierServicePackageNameForLogicalSlot(int);
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaEnhancedRoamingIndicatorDisplayNumber();
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn();
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn(int);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin();
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin(int);
-    method public String getCdmaPrlVersion();
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaRoamingMode();
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaSubscriptionMode();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaEnhancedRoamingIndicatorDisplayNumber();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn(int);
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin(int);
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public String getCdmaPrlVersion();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaRoamingMode();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaSubscriptionMode();
     method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS) public java.util.List<android.telephony.CellBroadcastIdRange> getCellBroadcastIdRanges();
     method public int getCurrentPhoneType();
     method public int getCurrentPhoneType(int);
@@ -16167,7 +16173,7 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void resetIms(int);
     method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void resetOtaEmergencyNumberDbFilePath();
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig();
     method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void resetSettings();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int sendThermalMitigationRequest(@NonNull android.telephony.ThermalMitigationRequest);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
@@ -16176,8 +16182,8 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCallWaitingEnabled(boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCdmaRoamingMode(int);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCdmaSubscriptionMode(int);
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCdmaRoamingMode(int);
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCdmaSubscriptionMode(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS) public void setCellBroadcastIdRanges(@NonNull java.util.List<android.telephony.CellBroadcastIdRange>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean);
@@ -16241,9 +16247,9 @@
     field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
     field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
     field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff
-    field public static final int CDMA_SUBSCRIPTION_NV = 1; // 0x1
-    field public static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; // 0x0
-    field public static final int CDMA_SUBSCRIPTION_UNKNOWN = -1; // 0xffffffff
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_SUBSCRIPTION_NV = 1; // 0x1
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; // 0x0
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_SUBSCRIPTION_UNKNOWN = -1; // 0xffffffff
     field public static final int CELL_BROADCAST_RESULT_FAIL_ACTIVATION = 3; // 0x3
     field public static final int CELL_BROADCAST_RESULT_FAIL_CONFIG = 2; // 0x2
     field public static final int CELL_BROADCAST_RESULT_SUCCESS = 0; // 0x0
@@ -16460,21 +16466,21 @@
 
 package android.telephony.cdma {
 
-  public final class CdmaSmsCbProgramData implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getCategory();
-    method public int getOperation();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 4099; // 0x1003
-    field public static final int CATEGORY_CMAS_EXTREME_THREAT = 4097; // 0x1001
-    field public static final int CATEGORY_CMAS_LAST_RESERVED_VALUE = 4351; // 0x10ff
-    field public static final int CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 4096; // 0x1000
-    field public static final int CATEGORY_CMAS_SEVERE_THREAT = 4098; // 0x1002
-    field public static final int CATEGORY_CMAS_TEST_MESSAGE = 4100; // 0x1004
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.cdma.CdmaSmsCbProgramData> CREATOR;
-    field public static final int OPERATION_ADD_CATEGORY = 1; // 0x1
-    field public static final int OPERATION_CLEAR_CATEGORIES = 2; // 0x2
-    field public static final int OPERATION_DELETE_CATEGORY = 0; // 0x0
+  @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public final class CdmaSmsCbProgramData implements android.os.Parcelable {
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int describeContents();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getCategory();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getOperation();
+    method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public void writeToParcel(android.os.Parcel, int);
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 4099; // 0x1003
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_EXTREME_THREAT = 4097; // 0x1001
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_LAST_RESERVED_VALUE = 4351; // 0x10ff
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 4096; // 0x1000
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_SEVERE_THREAT = 4098; // 0x1002
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_TEST_MESSAGE = 4100; // 0x1004
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public static final android.os.Parcelable.Creator<android.telephony.cdma.CdmaSmsCbProgramData> CREATOR;
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int OPERATION_ADD_CATEGORY = 1; // 0x1
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int OPERATION_CLEAR_CATEGORIES = 2; // 0x2
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int OPERATION_DELETE_CATEGORY = 0; // 0x0
   }
 
 }
@@ -17802,7 +17808,7 @@
     field public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 1; // 0x1
     field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G = 7; // 0x7
     field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 6; // 0x6
-    field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 4; // 0x4
+    field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 4; // 0x4
     field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS = 5; // 0x5
     field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_INTERNET_PDN = 12; // 0xc
     field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN = 9; // 0x9
@@ -18697,7 +18703,6 @@
     method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public void requestIsSupported(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Boolean,android.telephony.satellite.SatelliteManager.SatelliteException>);
     method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestNtnSignalStrength(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.telephony.satellite.NtnSignalStrength,android.telephony.satellite.SatelliteManager.SatelliteException>);
     method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestSatelliteAccessConfigurationForCurrentLocation(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.telephony.satellite.SatelliteAccessConfiguration,android.telephony.satellite.SatelliteManager.SatelliteException>);
-    method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestSatelliteDisplayName(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.CharSequence,android.telephony.satellite.SatelliteManager.SatelliteException>);
     method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestSatelliteSubscriberProvisionStatus(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.util.List<android.telephony.satellite.SatelliteSubscriberProvisionStatus>,android.telephony.satellite.SatelliteManager.SatelliteException>);
     method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestSelectedNbIotSatelliteSubscriptionId(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Integer,android.telephony.satellite.SatelliteManager.SatelliteException>);
     method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestTimeForNextSatelliteVisibility(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.time.Duration,android.telephony.satellite.SatelliteManager.SatelliteException>);
@@ -19136,6 +19141,20 @@
 
 }
 
+package android.view.textclassifier {
+
+  public final class TextClassificationManager {
+    method @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_TEXT_CLASSIFIER_BY_TYPE) public android.view.textclassifier.TextClassifier getClassifier(int);
+  }
+
+  public interface TextClassifier {
+    field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final int CLASSIFIER_TYPE_ANDROID_DEFAULT = 2; // 0x2
+    field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final int CLASSIFIER_TYPE_DEVICE_DEFAULT = 1; // 0x1
+    field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final int CLASSIFIER_TYPE_SELF_PROVIDED = 0; // 0x0
+  }
+
+}
+
 package android.view.translation {
 
   public final class TranslationCapability implements android.os.Parcelable {
diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt
index 7c43891..3b9ef959 100644
--- a/core/api/system-lint-baseline.txt
+++ b/core/api/system-lint-baseline.txt
@@ -505,6 +505,8 @@
 
 FlaggedApiLiteral: android.Manifest.permission#ACCESS_LAST_KNOWN_CELL_ID:
     @FlaggedApi contains a string literal, but should reference the field generated by aconfig (com.android.server.telecom.flags.Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES).
+FlaggedApiLiteral: android.Manifest.permission#ACCESS_TEXT_CLASSIFIER_BY_TYPE:
+    @FlaggedApi contains a string literal, but should reference the field generated by aconfig (android.permission.flags.Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED).
 FlaggedApiLiteral: android.Manifest.permission#BACKUP_HEALTH_CONNECT_DATA_AND_SETTINGS:
     @FlaggedApi contains a string literal, but should reference the field generated by aconfig (android.permission.flags.Flags.FLAG_HEALTH_CONNECT_BACKUP_RESTORE_PERMISSION_ENABLED).
 FlaggedApiLiteral: android.Manifest.permission#BIND_VERIFICATION_AGENT:
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 6230a59..8594cae 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1402,9 +1402,9 @@
     method @NonNull public android.credentials.selection.GetCredentialProviderData.Builder setRemoteEntry(@Nullable android.credentials.selection.Entry);
   }
 
-  @FlaggedApi("android.credentials.flags.configurable_selector_ui_enabled") public class IntentFactory {
-    method @NonNull public static android.content.Intent createCancelUiIntent(@NonNull android.content.Context, @NonNull android.os.IBinder, boolean, @NonNull String);
-    method @NonNull public static android.content.Intent createCredentialSelectorIntent(@NonNull android.content.Context, @NonNull android.credentials.selection.RequestInfo, @NonNull java.util.ArrayList<android.credentials.selection.ProviderData>, @NonNull java.util.ArrayList<android.credentials.selection.DisabledProviderData>, @NonNull android.os.ResultReceiver);
+  @FlaggedApi("android.credentials.flags.propagate_user_context_for_intent_creation") public class IntentFactory {
+    method @NonNull public static android.content.Intent createCancelUiIntent(@NonNull android.content.Context, @NonNull android.os.IBinder, boolean, @NonNull String, int);
+    method @NonNull public static android.content.Intent createCredentialSelectorIntent(@NonNull android.content.Context, @NonNull android.credentials.selection.RequestInfo, @NonNull java.util.ArrayList<android.credentials.selection.ProviderData>, @NonNull java.util.ArrayList<android.credentials.selection.DisabledProviderData>, @NonNull android.os.ResultReceiver, int);
   }
 
   @FlaggedApi("android.credentials.flags.configurable_selector_ui_enabled") public abstract class ProviderData implements android.os.Parcelable {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 38aea64..03ef669 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1279,7 +1279,24 @@
      *
      * <p>This method should be utilized when an activity wants to nudge the user to switch
      * to the web application in cases where the web may provide the user with a better
-     * experience. Note that this method does not guarantee that the education will be shown.</p>
+     * experience. Note that this method does not guarantee that the education will be shown.
+     *
+     * <p>The number of times that the "Open in browser" education can be triggered by this method
+     * is limited per application, and, when shown, the education appears above the app's content.
+     * For these reasons, developers should use this method sparingly when it is least
+     * disruptive to the user to show the education and when it is optimal to switch the user to a
+     * browser session. Before requesting to show the education, developers should assert that they
+     * have set a link that can be used by the "Open in browser" feature through either
+     * {@link AssistContent#EXTRA_AUTHENTICATING_USER_WEB_URI} or
+     * {@link AssistContent#setWebUri} so that users are navigated to a relevant page if they choose
+     * to switch to the browser. If a URI is not set using either method, "Open in browser" will
+     * utilize a generic link if available which will direct users to the homepage of the site
+     * associated with the app. The generic link is provided for a limited number of applications by
+     * the system and cannot be edited by developers. If none of these options contains a valid URI,
+     * the user will not be provided with the option to switch to the browser and the education will
+     * not be shown if requested.
+     *
+     * @see android.app.assist.AssistContent#EXTRA_SESSION_TRANSFER_WEB_URI
      */
     @FlaggedApi(com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB_EDUCATION)
     public final void requestOpenInBrowserEducation() {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 48b74f2..ec17333 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1975,8 +1975,12 @@
 
         @Override
         public void dumpCacheInfo(ParcelFileDescriptor pfd, String[] args) {
-            PropertyInvalidatedCache.dumpCacheInfo(pfd, args);
-            IoUtils.closeQuietly(pfd);
+            try {
+                PropertyInvalidatedCache.dumpCacheInfo(pfd, args);
+                BroadcastStickyCache.dumpCacheInfo(pfd);
+            } finally {
+                IoUtils.closeQuietly(pfd);
+            }
         }
 
         private File getDatabasesDir(Context context) {
diff --git a/core/java/android/app/AppOpsManager.aidl b/core/java/android/app/AppOpsManager.aidl
index 56ed290..b4dee2e 100644
--- a/core/java/android/app/AppOpsManager.aidl
+++ b/core/java/android/app/AppOpsManager.aidl
@@ -19,7 +19,6 @@
 parcelable AppOpsManager.PackageOps;
 parcelable AppOpsManager.NoteOpEventProxyInfo;
 parcelable AppOpsManager.NoteOpEvent;
-parcelable AppOpsManager.NotedOp;
 parcelable AppOpsManager.OpFeatureEntry;
 parcelable AppOpsManager.OpEntry;
 
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index c789e28..1913812 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -262,24 +262,6 @@
 
     private static final Object sLock = new Object();
 
-    // A map that records noted times for each op.
-    private final ArrayMap<NotedOp, Integer> mPendingNotedOps = new ArrayMap<>();
-    private final HandlerThread mHandlerThread;
-    private final Handler mHandler;
-    private static final int NOTE_OP_BATCHING_DELAY_MILLIS = 1000;
-
-    private boolean isNoteOpBatchingSupported() {
-        // If noteOp is called from system server no IPC is made, hence we don't need batching.
-        if (Process.myUid() == Process.SYSTEM_UID) {
-            return false;
-        }
-        return Flags.noteOpBatchingEnabled();
-    }
-
-    private final Object mBatchedNoteOpLock = new Object();
-    @GuardedBy("mBatchedNoteOpLock")
-    private boolean mIsBatchedNoteOpCallScheduled = false;
-
     /** Current {@link OnOpNotedCallback}. Change via {@link #setOnOpNotedCallback} */
     @GuardedBy("sLock")
     private static @Nullable OnOpNotedCallback sOnOpNotedCallback;
@@ -7484,135 +7466,6 @@
     }
 
     /**
-     * A NotedOp is an app op grouped in noteOp API and sent to the system server in a batch
-     *
-     * @hide
-     */
-    public static final class NotedOp implements Parcelable {
-        private final @IntRange(from = 0, to = _NUM_OP - 1) int mOp;
-        private final @IntRange(from = 0) int mUid;
-        private final @Nullable String mPackageName;
-        private final @Nullable String mAttributionTag;
-        private final int mVirtualDeviceId;
-        private final @Nullable String mMessage;
-        private final boolean mShouldCollectAsyncNotedOp;
-        private final boolean mShouldCollectMessage;
-
-        public NotedOp(int op, int uid, @Nullable String packageName,
-                @Nullable String attributionTag, int virtualDeviceId, @Nullable String message,
-                boolean shouldCollectAsyncNotedOp, boolean shouldCollectMessage) {
-            mOp = op;
-            mUid = uid;
-            mPackageName = packageName;
-            mAttributionTag = attributionTag;
-            mVirtualDeviceId = virtualDeviceId;
-            mMessage = message;
-            mShouldCollectAsyncNotedOp = shouldCollectAsyncNotedOp;
-            mShouldCollectMessage = shouldCollectMessage;
-        }
-
-        NotedOp(Parcel source) {
-            mOp = source.readInt();
-            mUid = source.readInt();
-            mPackageName = source.readString();
-            mAttributionTag = source.readString();
-            mVirtualDeviceId = source.readInt();
-            mMessage = source.readString();
-            mShouldCollectAsyncNotedOp = source.readBoolean();
-            mShouldCollectMessage = source.readBoolean();
-        }
-
-        public int getOp() {
-            return mOp;
-        }
-
-        public int getUid() {
-            return mUid;
-        }
-
-        public @Nullable String getPackageName() {
-            return mPackageName;
-        }
-
-        public @Nullable String getAttributionTag() {
-            return mAttributionTag;
-        }
-
-        public int getVirtualDeviceId() {
-            return mVirtualDeviceId;
-        }
-
-        public @Nullable String getMessage() {
-            return mMessage;
-        }
-
-        public boolean getShouldCollectAsyncNotedOp() {
-            return mShouldCollectAsyncNotedOp;
-        }
-
-        public boolean getShouldCollectMessage() {
-            return mShouldCollectMessage;
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(@NonNull Parcel dest, int flags) {
-            dest.writeInt(mOp);
-            dest.writeInt(mUid);
-            dest.writeString(mPackageName);
-            dest.writeString(mAttributionTag);
-            dest.writeInt(mVirtualDeviceId);
-            dest.writeString(mMessage);
-            dest.writeBoolean(mShouldCollectAsyncNotedOp);
-            dest.writeBoolean(mShouldCollectMessage);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-            NotedOp that = (NotedOp) o;
-            return mOp == that.mOp && mUid == that.mUid && Objects.equals(mPackageName,
-                    that.mPackageName) && Objects.equals(mAttributionTag, that.mAttributionTag)
-                    && mVirtualDeviceId == that.mVirtualDeviceId && Objects.equals(mMessage,
-                    that.mMessage) && Objects.equals(mShouldCollectAsyncNotedOp,
-                    that.mShouldCollectAsyncNotedOp) && Objects.equals(mShouldCollectMessage,
-                    that.mShouldCollectMessage);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mOp, mUid, mPackageName, mAttributionTag, mVirtualDeviceId,
-                    mMessage, mShouldCollectAsyncNotedOp, mShouldCollectMessage);
-        }
-
-        @Override
-        public String toString() {
-            return "NotedOp{" + "mOp=" + mOp + ", mUid=" + mUid + ", mPackageName=" + mPackageName
-                    + ", mAttributionTag=" + mAttributionTag + ", mVirtualDeviceId="
-                    + mVirtualDeviceId + ", mMessage=" + mMessage + ", mShouldCollectAsyncNotedOp="
-                    + mShouldCollectAsyncNotedOp + ", mShouldCollectMessage="
-                    + mShouldCollectMessage + "}";
-        }
-
-
-        public static final @NonNull Creator<NotedOp> CREATOR =
-                new Creator<>() {
-                    @Override public NotedOp createFromParcel(Parcel source) {
-                        return new NotedOp(source);
-                    }
-
-                    @Override public NotedOp[] newArray(int size) {
-                        return new NotedOp[size];
-                    }
-                };
-    }
-
-    /**
      * Computes the sum of the counts for the given flags in between the begin and
      * end UID states.
      *
@@ -8126,9 +7979,6 @@
     AppOpsManager(Context context, IAppOpsService service) {
         mContext = context;
         mService = service;
-        mHandlerThread = new HandlerThread("AppOpsManager");
-        mHandlerThread.start();
-        mHandler = mHandlerThread.getThreadHandler();
 
         if (mContext != null) {
             final PackageManager pm = mContext.getPackageManager();
@@ -9465,74 +9315,15 @@
                 }
             }
 
-            SyncNotedAppOp syncOp = null;
-            boolean skipBinderCall = false;
-            if (isNoteOpBatchingSupported()) {
-                int mode = sAppOpModeCache.query(
-                        new AppOpModeQuery(op, uid, packageName, virtualDeviceId, attributionTag,
-                                "noteOpNoThrow"));
-                // For FOREGROUND mode, we still need to make a binder call to the system service
-                // to translate it to ALLOWED or IGNORED. So no batching is needed.
-                if (mode != MODE_FOREGROUND) {
-                    synchronized (mBatchedNoteOpLock) {
-                        NotedOp notedOp = new NotedOp(op, uid, packageName, attributionTag,
-                                virtualDeviceId, message, collectionMode == COLLECT_ASYNC,
-                                shouldCollectMessage);
-
-                        // Batch same noteOp calls and send them with their counters to the system
-                        // service asynchronously. The time window for batching is specified in
-                        // NOTE_OP_BATCHING_DELAY_MILLIS. Always allow the first noteOp call to go
-                        // through binder API. Accumulate subsequent same noteOp calls during the
-                        // time window in mPendingNotedOps.
-                        if (!mPendingNotedOps.containsKey(notedOp)) {
-                            mPendingNotedOps.put(notedOp, 0);
-                        } else {
-                            skipBinderCall = true;
-                            mPendingNotedOps.merge(notedOp, 1, Integer::sum);
-                        }
-
-                        if (!mIsBatchedNoteOpCallScheduled) {
-                            mHandler.postDelayed(() -> {
-                                ArrayMap<NotedOp, Integer> pendingNotedOpsCopy;
-                                synchronized(mBatchedNoteOpLock) {
-                                    mIsBatchedNoteOpCallScheduled = false;
-                                    pendingNotedOpsCopy =
-                                            new ArrayMap<NotedOp, Integer>(mPendingNotedOps);
-                                    mPendingNotedOps.clear();
-                                }
-                                for (int i = pendingNotedOpsCopy.size() - 1; i >= 0; i--) {
-                                    if (pendingNotedOpsCopy.valueAt(i) == 0) {
-                                        pendingNotedOpsCopy.removeAt(i);
-                                    }
-                                }
-                                if (!pendingNotedOpsCopy.isEmpty()) {
-                                    try {
-                                        mService.noteOperationsInBatch(pendingNotedOpsCopy);
-                                    } catch (RemoteException e) {
-                                        throw e.rethrowFromSystemServer();
-                                    }
-                                }
-                            }, NOTE_OP_BATCHING_DELAY_MILLIS);
-
-                            mIsBatchedNoteOpCallScheduled = true;
-                        }
-                    }
-
-                    syncOp = new SyncNotedAppOp(mode, op, attributionTag, packageName);
-                }
+            SyncNotedAppOp syncOp;
+            if (virtualDeviceId == Context.DEVICE_ID_DEFAULT) {
+                syncOp = mService.noteOperation(op, uid, packageName, attributionTag,
+                        collectionMode == COLLECT_ASYNC, message, shouldCollectMessage);
+            } else {
+                syncOp = mService.noteOperationForDevice(op, uid, packageName, attributionTag,
+                    virtualDeviceId, collectionMode == COLLECT_ASYNC, message,
+                    shouldCollectMessage);
             }
-
-            if (!skipBinderCall) {
-                if (virtualDeviceId == Context.DEVICE_ID_DEFAULT) {
-                    syncOp = mService.noteOperation(op, uid, packageName, attributionTag,
-                            collectionMode == COLLECT_ASYNC, message, shouldCollectMessage);
-                } else {
-                    syncOp = mService.noteOperationForDevice(op, uid, packageName, attributionTag,
-                            virtualDeviceId, collectionMode == COLLECT_ASYNC, message,
-                            shouldCollectMessage);
-                }
-            }
-
             if (syncOp.getOpMode() == MODE_ALLOWED) {
                 if (collectionMode == COLLECT_SELF) {
                     collectNotedOpForSelf(syncOp);
diff --git a/core/java/android/app/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java
index 8b7ea0f..b21defb 100644
--- a/core/java/android/app/AppOpsManagerInternal.java
+++ b/core/java/android/app/AppOpsManagerInternal.java
@@ -29,7 +29,7 @@
 import com.android.internal.util.function.DodecFunction;
 import com.android.internal.util.function.HexConsumer;
 import com.android.internal.util.function.HexFunction;
-import com.android.internal.util.function.NonaFunction;
+import com.android.internal.util.function.OctFunction;
 import com.android.internal.util.function.QuadFunction;
 import com.android.internal.util.function.UndecFunction;
 
@@ -86,9 +86,9 @@
          */
         SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName,
                 @Nullable String featureId, int virtualDeviceId, boolean shouldCollectAsyncNotedOp,
-                @Nullable String message, boolean shouldCollectMessage, int notedCount,
-                @NonNull NonaFunction<Integer, Integer, String, String, Integer, Boolean, String,
-                        Boolean, Integer, SyncNotedAppOp> superImpl);
+                @Nullable String message, boolean shouldCollectMessage,
+                @NonNull OctFunction<Integer, Integer, String, String, Integer, Boolean, String,
+                        Boolean, SyncNotedAppOp> superImpl);
 
         /**
          * Allows overriding note proxy operation behavior.
diff --git a/core/java/android/app/BroadcastStickyCache.java b/core/java/android/app/BroadcastStickyCache.java
index fe2e107..0ffbf2c 100644
--- a/core/java/android/app/BroadcastStickyCache.java
+++ b/core/java/android/app/BroadcastStickyCache.java
@@ -30,13 +30,20 @@
 import android.net.wifi.p2p.WifiP2pManager;
 import android.os.IpcDataCache;
 import android.os.IpcDataCache.Config;
+import android.os.ParcelFileDescriptor;
 import android.os.UpdateLock;
 import android.telephony.TelephonyManager;
 import android.util.ArrayMap;
+import android.util.IndentingPrintWriter;
 import android.view.WindowManagerPolicyConstants;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.FastPrintWriter;
+
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
 
 /** @hide */
 public class BroadcastStickyCache {
@@ -71,8 +78,10 @@
     @VisibleForTesting
     public static final ArrayMap<String, String> sActionApiNameMap = new ArrayMap<>();
 
+    @GuardedBy("BroadcastStickyCache.class")
     private static final ArrayMap<String, IpcDataCache.Config> sActionConfigMap = new ArrayMap<>();
 
+    @GuardedBy("BroadcastStickyCache.class")
     private static final ArrayMap<StickyBroadcastFilter, IpcDataCache<Void, Intent>>
             sFilterCacheMap = new ArrayMap<>();
 
@@ -154,37 +163,44 @@
             @Nullable String broadcastPermission,
             @UserIdInt int userId,
             @RegisterReceiverFlags int flags) {
-        IpcDataCache<Void, Intent> intentDataCache = findIpcDataCache(filter);
+        IpcDataCache<Void, Intent> intentDataCache;
 
-        if (intentDataCache == null) {
-            final String action = filter.getAction(0);
-            final StickyBroadcastFilter stickyBroadcastFilter =
-                    new StickyBroadcastFilter(filter, action);
-            final Config config = getConfig(action);
+        synchronized (BroadcastStickyCache.class) {
+            intentDataCache = findIpcDataCache(filter);
 
-            intentDataCache =
-                    new IpcDataCache<>(config,
-                            (query) -> ActivityManager.getService().registerReceiverWithFeature(
-                                    applicationThread,
-                                    mBasePackageName,
-                                    attributionTag,
-                                    /* receiverId= */ "null",
-                                    /* receiver= */ null,
-                                    filter,
-                                    broadcastPermission,
-                                    userId,
-                                    flags));
-            sFilterCacheMap.put(stickyBroadcastFilter, intentDataCache);
+            if (intentDataCache == null) {
+                final String action = filter.getAction(0);
+                final StickyBroadcastFilter stickyBroadcastFilter =
+                        new StickyBroadcastFilter(filter, action);
+                final Config config = getConfig(action);
+
+                intentDataCache =
+                        new IpcDataCache<>(config,
+                                (query) -> ActivityManager.getService().registerReceiverWithFeature(
+                                        applicationThread,
+                                        mBasePackageName,
+                                        attributionTag,
+                                        /* receiverId= */ "null",
+                                        /* receiver= */ null,
+                                        filter,
+                                        broadcastPermission,
+                                        userId,
+                                        flags));
+                sFilterCacheMap.put(stickyBroadcastFilter, intentDataCache);
+            }
         }
         return intentDataCache.query(null);
     }
 
     @VisibleForTesting
     public static void clearCacheForTest() {
-        sFilterCacheMap.clear();
+        synchronized (BroadcastStickyCache.class) {
+            sFilterCacheMap.clear();
+        }
     }
 
     @Nullable
+    @GuardedBy("BroadcastStickyCache.class")
     private static IpcDataCache<Void, Intent> findIpcDataCache(
             @NonNull IntentFilter filter) {
         for (int i = sFilterCacheMap.size() - 1; i >= 0; i--) {
@@ -198,17 +214,56 @@
     }
 
     @NonNull
+    @GuardedBy("BroadcastStickyCache.class")
     private static IpcDataCache.Config getConfig(@NonNull String action) {
         if (!sActionConfigMap.containsKey(action)) {
             // We only need 1 entry per cache but just to be on the safer side we are choosing 32
             // although we don't expect more than 1.
             sActionConfigMap.put(action,
-                    new Config(32, IpcDataCache.MODULE_SYSTEM, sActionApiNameMap.get(action)));
+                    new Config(32, IpcDataCache.MODULE_SYSTEM,
+                            sActionApiNameMap.get(action)).cacheNulls(true));
         }
 
         return sActionConfigMap.get(action);
     }
 
+    public static void dumpCacheInfo(@NonNull ParcelFileDescriptor pfd) {
+        if (!Flags.useStickyBcastCache()) {
+            return;
+        }
+        final PrintWriter pw = new FastPrintWriter(new FileOutputStream(pfd.getFileDescriptor()));
+        synchronized (BroadcastStickyCache.class) {
+            dumpCacheLocked(pw);
+        }
+        pw.flush();
+    }
+
+    @GuardedBy("BroadcastStickyCache.class")
+    private static void dumpCacheLocked(@NonNull PrintWriter pw) {
+        final IndentingPrintWriter ipw = new IndentingPrintWriter(
+                pw, "  " /* singleIndent */, "  " /* prefix */);
+        ipw.println("Cached sticky broadcasts:");
+        ipw.increaseIndent();
+        final int count = sFilterCacheMap.size();
+        if (count == 0) {
+            ipw.println("<empty>");
+        } else {
+            for (int i = 0; i < count; ++i) {
+                final StickyBroadcastFilter stickyBroadcast = sFilterCacheMap.keyAt(i);
+                final IpcDataCache<Void, Intent> ipcDataCache = sFilterCacheMap.valueAt(i);
+                ipw.print("Entry #");
+                ipw.print(i);
+                ipw.println(":");
+                ipw.increaseIndent();
+                ipw.print("action", stickyBroadcast.action).println();
+                ipw.print("filter", stickyBroadcast.filter.toLongString()).println();
+                ipcDataCache.dumpCacheEntries(pw);
+                ipw.decreaseIndent();
+            }
+        }
+        ipw.decreaseIndent();
+    }
+
     @VisibleForTesting
     private record StickyBroadcastFilter(@NonNull IntentFilter filter, @NonNull String action) {
     }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 7e998d9..aa2ada5 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -6024,8 +6024,9 @@
         /**
          * @param isHeader If the notification is a notification header
          * @return An instance of mColors after resolving the palette
+         * @hide
          */
-        private Colors getColors(boolean isHeader) {
+        public Colors getColors(boolean isHeader) {
             mColors.resolvePalette(mContext, mN.color, !isHeader && mN.isColorized(), mInNightMode);
             return mColors;
         }
@@ -14765,7 +14766,6 @@
      * A utility which stores and calculates the palette of colors used to color notifications.
      * @hide
      */
-    @VisibleForTesting
     public static class Colors {
         private int mPaletteIsForRawColor = COLOR_INVALID;
         private boolean mPaletteIsForColorized = false;
@@ -14839,10 +14839,7 @@
 
             if (isColorized) {
                 if (rawColor == COLOR_DEFAULT) {
-                    int[] attrs = {R.attr.materialColorSecondary};
-                    try (TypedArray ta = obtainDayNightAttributes(ctx, attrs)) {
-                        mBackgroundColor = getColor(ta, 0, Color.WHITE);
-                    }
+                    mBackgroundColor = ctx.getColor(R.color.materialColorSecondary);
                 } else {
                     mBackgroundColor = rawColor;
                 }
@@ -14874,30 +14871,25 @@
                 mRippleAlpha = 0x33;
             } else {
                 int[] attrs = {
-                        R.attr.materialColorSurfaceContainerHigh,
-                        R.attr.materialColorOnSurface,
-                        R.attr.materialColorOnSurfaceVariant,
-                        R.attr.materialColorPrimary,
-                        R.attr.materialColorSecondary,
-                        R.attr.materialColorTertiary,
-                        R.attr.materialColorOnTertiary,
-                        R.attr.materialColorTertiaryFixedDim,
-                        R.attr.materialColorOnTertiaryFixed,
                         R.attr.colorError,
                         R.attr.colorControlHighlight
                 };
+
+                mBackgroundColor = ctx.getColor(R.color.materialColorSurfaceContainerHigh);
+                mPrimaryTextColor = ctx.getColor(R.color.materialColorOnSurface);
+                mSecondaryTextColor = ctx.getColor(R.color.materialColorOnSurfaceVariant);
+                mPrimaryAccentColor = ctx.getColor(R.color.materialColorPrimary);
+                mSecondaryAccentColor = ctx.getColor(R.color.materialColorSecondary);
+                mTertiaryAccentColor = ctx.getColor(R.color.materialColorTertiary);
+                mOnTertiaryAccentTextColor = ctx.getColor(R.color.materialColorOnTertiary);
+                mTertiaryFixedDimAccentColor = ctx.getColor(
+                        R.color.materialColorTertiaryFixedDim);
+                mOnTertiaryFixedAccentTextColor = ctx.getColor(
+                        R.color.materialColorOnTertiaryFixed);
+
                 try (TypedArray ta = obtainDayNightAttributes(ctx, attrs)) {
-                    mBackgroundColor = getColor(ta, 0, nightMode ? Color.BLACK : Color.WHITE);
-                    mPrimaryTextColor = getColor(ta, 1, COLOR_INVALID);
-                    mSecondaryTextColor = getColor(ta, 2, COLOR_INVALID);
-                    mPrimaryAccentColor = getColor(ta, 3, COLOR_INVALID);
-                    mSecondaryAccentColor = getColor(ta, 4, COLOR_INVALID);
-                    mTertiaryAccentColor = getColor(ta, 5, COLOR_INVALID);
-                    mOnTertiaryAccentTextColor = getColor(ta, 6, COLOR_INVALID);
-                    mTertiaryFixedDimAccentColor = getColor(ta, 7, COLOR_INVALID);
-                    mOnTertiaryFixedAccentTextColor = getColor(ta, 8, COLOR_INVALID);
-                    mErrorColor = getColor(ta, 9, COLOR_INVALID);
-                    mRippleAlpha = Color.alpha(getColor(ta, 10, 0x33ffffff));
+                    mErrorColor = getColor(ta, 0, COLOR_INVALID);
+                    mRippleAlpha = Color.alpha(getColor(ta, 1, 0x33ffffff));
                 }
                 mContrastColor = calculateContrastColor(ctx, rawColor, mPrimaryAccentColor,
                         mBackgroundColor, nightMode);
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 87c8619..8ed66eb 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -49,7 +49,6 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.Handler;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -61,15 +60,18 @@
 import android.provider.Settings.Global;
 import android.service.notification.Adjustment;
 import android.service.notification.Condition;
+import android.service.notification.RateEstimator;
 import android.service.notification.StatusBarNotification;
 import android.service.notification.ZenDeviceEffects;
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenPolicy;
 import android.util.Log;
+import android.util.LruCache;
 import android.util.proto.ProtoOutputStream;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.time.InstantSource;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -643,9 +645,17 @@
      */
     public static int MAX_SERVICE_COMPONENT_NAME_LENGTH = 500;
 
+    private static final float MAX_NOTIFICATION_ENQUEUE_RATE = 5f;
+
+    private final Context mContext;
     private final Map<CallNotificationEventListener, CallNotificationEventCallbackStub>
             mCallNotificationEventCallbacks = new HashMap<>();
 
+    private final InstantSource mClock;
+    private final RateEstimator mEnqueueRateEstimator = new RateEstimator();
+    private final LruCache<String, Boolean> mEnqueuedNotificationKeys = new LruCache<>(10);
+    private final Object mEnqueueThrottleLock = new Object();
+
     @UnsupportedAppUsage
     private static INotificationManager sService;
 
@@ -661,10 +671,17 @@
         return sService;
     }
 
+    /** @hide */
+    protected INotificationManager service() {
+        return getService();
+    }
+
+    /** {@hide} */
     @UnsupportedAppUsage
-    /*package*/ NotificationManager(Context context, Handler handler)
+    public NotificationManager(Context context, InstantSource clock)
     {
         mContext = context;
+        mClock = clock;
     }
 
     /** {@hide} */
@@ -736,7 +753,7 @@
      */
     public void notifyAsPackage(@NonNull String targetPackage, @Nullable String tag, int id,
             @NonNull Notification notification) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         String sender = mContext.getPackageName();
 
         try {
@@ -752,13 +769,12 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
+    public void notifyAsUser(@Nullable String tag, int id, Notification notification,
+            UserHandle user)
     {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         String pkg = mContext.getPackageName();
-
-        if (notificationClassification()
-                && NotificationChannel.SYSTEM_RESERVED_IDS.contains(notification.getChannelId())) {
+        if (discardNotify(tag, id, notification)) {
             return;
         }
 
@@ -771,6 +787,37 @@
         }
     }
 
+    /**
+     * Determines whether a {@link #notify} call should be skipped. If the notification is not
+     * skipped, updates tracking metadata to use in future decisions.
+     */
+    private boolean discardNotify(@Nullable String tag, int id, Notification notification) {
+        if (notificationClassification()
+                && NotificationChannel.SYSTEM_RESERVED_IDS.contains(notification.getChannelId())) {
+            return true;
+        }
+
+        if (Flags.nmBinderPerfThrottleNotify()) {
+            String key = toEnqueuedNotificationKey(tag, id);
+            long now = mClock.millis();
+            synchronized (mEnqueueThrottleLock) {
+                if (mEnqueuedNotificationKeys.get(key) != null
+                        && !notification.hasCompletedProgress()
+                        && mEnqueueRateEstimator.getRate(now) > MAX_NOTIFICATION_ENQUEUE_RATE) {
+                    return true;
+                }
+
+                mEnqueueRateEstimator.update(now);
+                mEnqueuedNotificationKeys.put(key, Boolean.TRUE);
+            }
+        }
+
+        return false;
+    }
+    private static String toEnqueuedNotificationKey(@Nullable String tag, int id) {
+        return tag + "," + id;
+    }
+
     private Notification fixNotification(Notification notification) {
         String pkg = mContext.getPackageName();
         // Fix the notification as best we can.
@@ -852,7 +899,7 @@
      * @param id An identifier for this notification.
      */
     public void cancelAsPackage(@NonNull String targetPackage, @Nullable String tag, int id) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.cancelNotificationWithTag(targetPackage, mContext.getOpPackageName(),
                     tag, id, mContext.getUser().getIdentifier());
@@ -865,9 +912,15 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public void cancelAsUser(String tag, int id, UserHandle user)
+    public void cancelAsUser(@Nullable String tag, int id, UserHandle user)
     {
-        INotificationManager service = getService();
+        if (Flags.nmBinderPerfThrottleNotify()) {
+            synchronized (mEnqueueThrottleLock) {
+                mEnqueuedNotificationKeys.remove(toEnqueuedNotificationKey(tag, id));
+            }
+        }
+
+        INotificationManager service = service();
         String pkg = mContext.getPackageName();
         if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
         try {
@@ -884,7 +937,13 @@
      */
     public void cancelAll()
     {
-        INotificationManager service = getService();
+        if (Flags.nmBinderPerfThrottleNotify()) {
+            synchronized (mEnqueueThrottleLock) {
+                mEnqueuedNotificationKeys.evictAll();
+            }
+        }
+
+        INotificationManager service = service();
         String pkg = mContext.getPackageName();
         if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
         try {
@@ -907,7 +966,7 @@
      * @param delegate Package name of the app which can send notifications on your behalf.
      */
     public void setNotificationDelegate(@Nullable String delegate) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         String pkg = mContext.getPackageName();
         if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
         try {
@@ -922,7 +981,7 @@
      * your behalf, if there currently is one.
      */
     public @Nullable String getNotificationDelegate() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         String pkg = mContext.getPackageName();
         try {
             return service.getNotificationDelegate(pkg);
@@ -938,7 +997,7 @@
      * See {@link #setNotificationDelegate(String)}.
      */
     public boolean canNotifyAsPackage(@NonNull String pkg) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.canNotifyAsPackage(mContext.getPackageName(), pkg, mContext.getUserId());
         } catch (RemoteException e) {
@@ -956,7 +1015,7 @@
      * {@link android.provider.Settings#ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT}.
      */
     public boolean canUseFullScreenIntent() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.canUseFullScreenIntent(mContext.getAttributionSource());
         } catch (RemoteException e) {
@@ -974,7 +1033,7 @@
      */
     @FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING)
     public boolean canPostPromotedNotifications() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.canBePromoted(mContext.getPackageName());
         } catch (RemoteException e) {
@@ -989,7 +1048,7 @@
     @TestApi
     @FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING)
     public void setCanPostPromotedNotifications(@NonNull String pkg, int uid, boolean allowed) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.setCanBePromoted(pkg, uid, allowed, true);
         } catch (RemoteException e) {
@@ -1024,7 +1083,7 @@
      * @param groups The list of groups to create
      */
     public void createNotificationChannelGroups(@NonNull List<NotificationChannelGroup> groups) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.createNotificationChannelGroups(mContext.getPackageName(),
                     new ParceledListSlice(groups));
@@ -1067,7 +1126,7 @@
      * @param channels the list of channels to attempt to create.
      */
     public void createNotificationChannels(@NonNull List<NotificationChannel> channels) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.createNotificationChannels(mContext.getPackageName(),
                     new ParceledListSlice(channels));
@@ -1085,7 +1144,7 @@
      * package (see {@link Context#createPackageContext(String, int)}).</p>
      */
     public NotificationChannel getNotificationChannel(String channelId) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getNotificationChannel(mContext.getOpPackageName(),
                     mContext.getUserId(), mContext.getPackageName(), channelId);
@@ -1105,7 +1164,7 @@
      */
     public @Nullable NotificationChannel getNotificationChannel(@NonNull String channelId,
             @NonNull String conversationId) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getConversationNotificationChannel(mContext.getOpPackageName(),
                     mContext.getUserId(), mContext.getPackageName(), channelId, true,
@@ -1124,7 +1183,7 @@
      * {@link Context#createPackageContext(String, int)}).</p>
      */
     public List<NotificationChannel> getNotificationChannels() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getNotificationChannels(mContext.getOpPackageName(),
                     mContext.getPackageName(), mContext.getUserId()).getList();
@@ -1145,7 +1204,7 @@
                 && NotificationChannel.SYSTEM_RESERVED_IDS.contains(channelId)) {
             return;
         }
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.deleteNotificationChannel(mContext.getPackageName(), channelId);
         } catch (RemoteException e) {
@@ -1159,7 +1218,7 @@
      * The channel group must belong to your package, or null will be returned.
      */
     public NotificationChannelGroup getNotificationChannelGroup(String channelGroupId) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getNotificationChannelGroup(mContext.getPackageName(), channelGroupId);
         } catch (RemoteException e) {
@@ -1171,7 +1230,7 @@
      * Returns all notification channel groups belonging to the calling app.
      */
     public List<NotificationChannelGroup> getNotificationChannelGroups() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             final ParceledListSlice<NotificationChannelGroup> parceledList =
                     service.getNotificationChannelGroups(mContext.getPackageName());
@@ -1189,7 +1248,7 @@
      * belong to it.
      */
     public void deleteNotificationChannelGroup(String groupId) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.deleteNotificationChannelGroup(mContext.getPackageName(), groupId);
         } catch (RemoteException e) {
@@ -1203,7 +1262,7 @@
     @TestApi
     public void updateNotificationChannel(@NonNull String pkg, int uid,
             @NonNull NotificationChannel channel) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.updateNotificationChannelForPackage(pkg, uid, channel);
         } catch (RemoteException e) {
@@ -1216,7 +1275,7 @@
      */
     @TestApi
     public ComponentName getEffectsSuppressor() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getEffectsSuppressor();
         } catch (RemoteException e) {
@@ -1228,7 +1287,7 @@
      * @hide
      */
     public boolean matchesCallFilter(Bundle extras) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.matchesCallFilter(extras);
         } catch (RemoteException e) {
@@ -1241,7 +1300,7 @@
      */
     @TestApi
     public void cleanUpCallersAfter(long timeThreshold) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.cleanUpCallersAfter(timeThreshold);
         } catch (RemoteException e) {
@@ -1253,7 +1312,7 @@
      * @hide
      */
     public boolean isSystemConditionProviderEnabled(String path) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.isSystemConditionProviderEnabled(path);
         } catch (RemoteException e) {
@@ -1271,7 +1330,7 @@
 
     /** @hide */
     public void setZenMode(int mode, Uri conditionId, String reason, boolean fromUser) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.setZenMode(mode, conditionId, reason, fromUser);
         } catch (RemoteException e) {
@@ -1284,7 +1343,7 @@
      * @hide
      */
     public int getZenMode() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getZenMode();
         } catch (RemoteException e) {
@@ -1297,7 +1356,7 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public ZenModeConfig getZenModeConfig() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getZenModeConfig();
         } catch (RemoteException e) {
@@ -1315,7 +1374,7 @@
      * </p>
      */
     public @NonNull NotificationManager.Policy getConsolidatedNotificationPolicy() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getConsolidatedNotificationPolicy();
         } catch (RemoteException e) {
@@ -1327,7 +1386,7 @@
      * @hide
      */
     public int getRuleInstanceCount(ComponentName owner) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getRuleInstanceCount(owner);
         } catch (RemoteException e) {
@@ -1364,7 +1423,7 @@
      * See {@link #isNotificationPolicyAccessGranted}.
      */
     public Map<String, AutomaticZenRule> getAutomaticZenRules() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             if (Flags.modesApi()) {
                 return service.getAutomaticZenRules();
@@ -1398,7 +1457,7 @@
      * doesn't own the matching rule. See {@link AutomaticZenRule#getOwner}.
      */
     public AutomaticZenRule getAutomaticZenRule(String id) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getAutomaticZenRule(id);
         } catch (RemoteException e) {
@@ -1426,7 +1485,7 @@
     @NonNull
     public String addAutomaticZenRule(@NonNull AutomaticZenRule automaticZenRule,
             boolean fromUser) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.addAutomaticZenRule(automaticZenRule,
                     mContext.getPackageName(), fromUser);
@@ -1461,7 +1520,7 @@
     @FlaggedApi(Flags.FLAG_MODES_API)
     public boolean updateAutomaticZenRule(@NonNull String id,
             @NonNull AutomaticZenRule automaticZenRule, boolean fromUser) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.updateAutomaticZenRule(id, automaticZenRule, fromUser);
         } catch (RemoteException e) {
@@ -1481,7 +1540,7 @@
     @FlaggedApi(Flags.FLAG_MODES_API)
     @Condition.State
     public int getAutomaticZenRuleState(@NonNull String id) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getAutomaticZenRuleState(id);
         } catch (RemoteException e) {
@@ -1527,7 +1586,7 @@
      * @param condition The new state of this rule
      */
     public void setAutomaticZenRuleState(@NonNull String id, @NonNull Condition condition) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.setAutomaticZenRuleState(id, condition);
         } catch (RemoteException e) {
@@ -1555,7 +1614,7 @@
     @TestApi
     @FlaggedApi(Flags.FLAG_MODES_API)
     public boolean removeAutomaticZenRule(@NonNull String id, boolean fromUser) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.removeAutomaticZenRule(id, fromUser);
         } catch (RemoteException e) {
@@ -1574,7 +1633,7 @@
 
     /** @hide */
     public boolean removeAutomaticZenRules(String packageName, boolean fromUser) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.removeAutomaticZenRules(packageName, fromUser);
         } catch (RemoteException e) {
@@ -1587,7 +1646,7 @@
      * package.
      */
     public @Importance int getImportance() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getPackageImportance(mContext.getPackageName());
         } catch (RemoteException e) {
@@ -1602,7 +1661,7 @@
         if (Flags.nmBinderPerfPermissionCheck()) {
             return mContext.checkSelfPermission(POST_NOTIFICATIONS) == PERMISSION_GRANTED;
         } else {
-            INotificationManager service = getService();
+            INotificationManager service = service();
             try {
                 return service.areNotificationsEnabled(mContext.getPackageName());
             } catch (RemoteException e) {
@@ -1623,7 +1682,7 @@
      */
     @Deprecated
     public boolean areBubblesAllowed() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.areBubblesAllowed(mContext.getPackageName());
         } catch (RemoteException e) {
@@ -1638,7 +1697,7 @@
      * @see Notification.Builder#setBubbleMetadata(Notification.BubbleMetadata)
      */
     public boolean areBubblesEnabled() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.areBubblesEnabled(mContext.getUser());
         } catch (RemoteException e) {
@@ -1665,7 +1724,7 @@
      * @return the users' bubble preference for the app.
      */
     public @BubblePreference int getBubblePreference() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getBubblePreferenceForPackage(mContext.getPackageName(),
                     Binder.getCallingUid());
@@ -1685,7 +1744,7 @@
      * @hide
      */
     public void silenceNotificationSound() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.silenceNotificationSound();
         } catch (RemoteException e) {
@@ -1701,7 +1760,7 @@
      * PersistableBundle, SuspendDialogInfo) suspended}.
      */
     public boolean areNotificationsPaused() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.isPackagePaused(mContext.getPackageName());
         } catch (RemoteException e) {
@@ -1724,7 +1783,7 @@
      * user grant or denial of this access.
      */
     public boolean isNotificationPolicyAccessGranted() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName());
         } catch (RemoteException e) {
@@ -1745,7 +1804,7 @@
      * {@link android.provider.Settings#ACTION_NOTIFICATION_LISTENER_SETTINGS}.
      */
     public boolean isNotificationListenerAccessGranted(ComponentName listener) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.isNotificationListenerAccessGranted(listener);
         } catch (RemoteException e) {
@@ -1769,7 +1828,7 @@
      */
     @SystemApi
     public boolean isNotificationAssistantAccessGranted(@NonNull ComponentName assistant) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.isNotificationAssistantAccessGranted(assistant);
         } catch (RemoteException e) {
@@ -1785,7 +1844,7 @@
      * listeners}.
      */
     public boolean shouldHideSilentStatusBarIcons() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.shouldHideSilentStatusIcons(mContext.getOpPackageName());
         } catch (RemoteException e) {
@@ -1804,7 +1863,7 @@
      */
     @SystemApi
     public @NonNull @Adjustment.Keys List<String> getAllowedAssistantAdjustments() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getAllowedAssistantAdjustments(mContext.getOpPackageName());
         } catch (RemoteException e) {
@@ -1818,7 +1877,7 @@
     @TestApi
     @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
     public void allowAssistantAdjustment(@NonNull String capability) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.allowAssistantAdjustment(capability);
         } catch (RemoteException e) {
@@ -1832,7 +1891,7 @@
     @TestApi
     @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
     public void disallowAssistantAdjustment(@NonNull String capability) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.disallowAssistantAdjustment(capability);
         } catch (RemoteException e) {
@@ -1843,7 +1902,7 @@
     /** @hide */
     @TestApi
     public boolean isNotificationPolicyAccessGrantedForPackage(@NonNull String pkg) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.isNotificationPolicyAccessGrantedForPackage(pkg);
         } catch (RemoteException e) {
@@ -1857,7 +1916,7 @@
     @TestApi
     @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
     public void setAssistantAdjustmentKeyTypeState(@Adjustment.Types int type, boolean enabled) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.setAssistantAdjustmentKeyTypeState(type, enabled);
         } catch (RemoteException e) {
@@ -1870,7 +1929,7 @@
      */
     @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
     public void setTypeAdjustmentForPackageState(@NonNull String pkg, boolean enabled) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.setTypeAdjustmentForPackageState(pkg, enabled);
         } catch (RemoteException e) {
@@ -1882,7 +1941,7 @@
      * @hide
      */
     public List<String> getEnabledNotificationListenerPackages() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getEnabledNotificationListenerPackages();
         } catch (RemoteException e) {
@@ -1899,7 +1958,7 @@
      * {@link #setNotificationPolicy(Policy)}.
      */
     public Policy getNotificationPolicy() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getNotificationPolicy(mContext.getOpPackageName());
         } catch (RemoteException e) {
@@ -1929,7 +1988,7 @@
     /** @hide */
     public void setNotificationPolicy(@NonNull Policy policy, boolean fromUser) {
         checkRequired("policy", policy);
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.setNotificationPolicy(mContext.getOpPackageName(), policy, fromUser);
         } catch (RemoteException e) {
@@ -1939,7 +1998,7 @@
 
     /** @hide */
     public void setNotificationPolicyAccessGranted(String pkg, boolean granted) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.setNotificationPolicyAccessGranted(pkg, granted);
         } catch (RemoteException e) {
@@ -1959,7 +2018,7 @@
     @TestApi
     @FlaggedApi(Flags.FLAG_MODES_API)
     public @NonNull ZenPolicy getDefaultZenPolicy() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getDefaultZenPolicy();
         } catch (RemoteException e) {
@@ -1971,7 +2030,7 @@
      */
     @FlaggedApi(Flags.FLAG_MODES_UI)
     public void setManualZenRuleDeviceEffects(@NonNull ZenDeviceEffects effects) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.setManualZenRuleDeviceEffects(effects);
         } catch (RemoteException e) {
@@ -2008,7 +2067,7 @@
     @RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS)
     public void setNotificationListenerAccessGranted(
             @NonNull ComponentName listener, boolean granted, boolean userSet) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             if (CompatChanges.isChangeEnabled(SET_LISTENER_ACCESS_GRANTED_IS_USER_AWARE)) {
                 service.setNotificationListenerAccessGrantedForUser(listener, mContext.getUserId(),
@@ -2024,7 +2083,7 @@
     /** @hide */
     public void setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId,
             boolean granted) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.setNotificationListenerAccessGrantedForUser(listener, userId, granted, true);
         } catch (RemoteException e) {
@@ -2045,7 +2104,7 @@
     @SystemApi
     public void setNotificationAssistantAccessGranted(@Nullable ComponentName assistant,
             boolean granted) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.setNotificationAssistantAccessGranted(assistant, granted);
         } catch (RemoteException e) {
@@ -2069,7 +2128,7 @@
 
     /** @hide */
     public List<ComponentName> getEnabledNotificationListeners(int userId) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getEnabledNotificationListeners(userId);
         } catch (RemoteException e) {
@@ -2080,7 +2139,7 @@
     /** @hide */
     @SystemApi
     public @Nullable ComponentName getAllowedNotificationAssistant() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.getAllowedNotificationAssistant();
         } catch (RemoteException e) {
@@ -2100,16 +2159,13 @@
     @SuppressLint("UserHandle")
     public boolean hasEnabledNotificationListener(@NonNull String packageName,
             @NonNull UserHandle userHandle) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return service.hasEnabledNotificationListener(packageName, userHandle.getIdentifier());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
-
-    private Context mContext;
-
     private static void checkRequired(String name, Object value) {
         if (value == null) {
             throw new IllegalArgumentException(name + " is required");
@@ -2125,7 +2181,7 @@
     @TestApi
     @RequiresPermission(android.Manifest.permission.MANAGE_TOAST_RATE_LIMITING)
     public void setToastRateLimitingEnabled(boolean enable) {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             service.setToastRateLimitingEnabled(enable);
         } catch (RemoteException e) {
@@ -2917,7 +2973,7 @@
      * @return An array of {@link StatusBarNotification}.
      */
     public StatusBarNotification[] getActiveNotifications() {
-        final INotificationManager service = getService();
+        final INotificationManager service = service();
         final String pkg = mContext.getPackageName();
         try {
             final ParceledListSlice<StatusBarNotification> parceledList
@@ -2940,7 +2996,7 @@
      * globally.
      */
     public final @InterruptionFilter int getCurrentInterruptionFilter() {
-        final INotificationManager service = getService();
+        final INotificationManager service = service();
         try {
             return zenModeToInterruptionFilter(service.getZenMode());
         } catch (RemoteException e) {
@@ -2972,7 +3028,7 @@
     /** @hide */
     public final void setInterruptionFilter(@InterruptionFilter int interruptionFilter,
             boolean fromUser) {
-        final INotificationManager service = getService();
+        final INotificationManager service = service();
         try {
             service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter,
                     fromUser);
@@ -3130,7 +3186,7 @@
         checkRequired("userHandle", userHandle);
         checkRequired("executor", executor);
         checkRequired("listener", listener);
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             synchronized (mCallNotificationEventCallbacks) {
                 CallNotificationEventCallbackStub callbackStub =
@@ -3161,7 +3217,7 @@
     public void unregisterCallNotificationEventListener(
             @NonNull CallNotificationEventListener listener) {
         checkRequired("listener", listener);
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             synchronized (mCallNotificationEventCallbacks) {
                 CallNotificationEventCallbackStub callbackStub =
@@ -3184,7 +3240,7 @@
     @TestApi
     @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
     public @NonNull Set<String> getUnsupportedAdjustmentTypes() {
-        INotificationManager service = getService();
+        INotificationManager service = service();
         try {
             return new HashSet<>(service.getUnsupportedAdjustmentTypes());
         } catch (RemoteException e) {
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index 1e971a5..c72c4c8 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -17,13 +17,13 @@
 package android.app;
 
 import static android.text.TextUtils.formatSimple;
+
 import static com.android.internal.util.Preconditions.checkArgumentPositive;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.os.Binder;
-import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -2326,6 +2326,19 @@
     }
 
     /**
+     * This dumps the detailed entries (Query and Result) inside the current instance of the
+     * {@link PropertyInvalidatedCache}.
+     *
+     * @param pw The PrintWriter object for the output stream.
+     * @hide
+     */
+    public void dumpCacheEntries(@NonNull PrintWriter pw) {
+        synchronized (mLock) {
+            mCache.dumpDetailed(pw);
+        }
+    }
+
+    /**
      * Nonces in shared memory are supported by a string block that acts as a table of contents
      * for nonce names, and an array of nonce values.  There are two key design principles with
      * respect to nonce maps:
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 248e0433..920b19c 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -289,6 +289,7 @@
 import com.android.internal.policy.PhoneLayoutInflater;
 import com.android.internal.util.Preconditions;
 
+import java.time.InstantSource;
 import java.util.Map;
 import java.util.Objects;
 
@@ -625,7 +626,7 @@
                                     com.android.internal.R.style.Theme_Holo_Dialog,
                                     com.android.internal.R.style.Theme_DeviceDefault_Dialog,
                                     com.android.internal.R.style.Theme_DeviceDefault_Light_Dialog)),
-                    ctx.mMainThread.getHandler());
+                    InstantSource.system());
             }});
 
         registerService(Context.PEOPLE_SERVICE, PeopleManager.class,
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index 637187e..e93d8bdb 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -157,6 +157,10 @@
             "file_patterns": ["(/|^)ContextImpl.java"]
         },
         {
+            "name": "BroadcastUnitTests",
+            "file_patterns": ["(/|^)BroadcastStickyCache.java"]
+        },
+        {
             "file_patterns": [
                 "(/|^)Activity.*.java",
                 "(/|^)PendingIntent.java",
@@ -177,10 +181,6 @@
         {
             "file_patterns": ["(/|^)AppOpsManager.java"],
             "name": "CtsAppOpsTestCases"
-        },
-        {
-            "file_patterns": ["(/|^)BroadcastStickyCache.java"],
-            "name": "BroadcastUnitTests"
         }
     ]
 }
diff --git a/core/java/android/app/appfunctions/AppFunctionManager.java b/core/java/android/app/appfunctions/AppFunctionManager.java
index ed088fe..a731e50 100644
--- a/core/java/android/app/appfunctions/AppFunctionManager.java
+++ b/core/java/android/app/appfunctions/AppFunctionManager.java
@@ -34,6 +34,7 @@
 import android.os.OutcomeReceiver;
 import android.os.ParcelableException;
 import android.os.RemoteException;
+import android.os.SystemClock;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -179,7 +180,8 @@
 
         ExecuteAppFunctionAidlRequest aidlRequest =
                 new ExecuteAppFunctionAidlRequest(
-                        request, mContext.getUser(), mContext.getPackageName());
+                        request, mContext.getUser(), mContext.getPackageName(),
+                        /* requestTime= */ SystemClock.elapsedRealtime());
 
         try {
             ICancellationSignal cancellationTransport =
diff --git a/core/java/android/app/appfunctions/ExecuteAppFunctionAidlRequest.java b/core/java/android/app/appfunctions/ExecuteAppFunctionAidlRequest.java
index e623fa1..707d1fc 100644
--- a/core/java/android/app/appfunctions/ExecuteAppFunctionAidlRequest.java
+++ b/core/java/android/app/appfunctions/ExecuteAppFunctionAidlRequest.java
@@ -41,8 +41,9 @@
                             ExecuteAppFunctionRequest.CREATOR.createFromParcel(in);
                     UserHandle userHandle = UserHandle.CREATOR.createFromParcel(in);
                     String callingPackage = in.readString8();
+                    long requestTime = in.readLong();
                     return new ExecuteAppFunctionAidlRequest(
-                            clientRequest, userHandle, callingPackage);
+                            clientRequest, userHandle, callingPackage, requestTime);
                 }
 
                 @Override
@@ -60,11 +61,15 @@
     /** The package name of the app that is requesting to execute the app function. */
     private final String mCallingPackage;
 
-    public ExecuteAppFunctionAidlRequest(
-            ExecuteAppFunctionRequest clientRequest, UserHandle userHandle, String callingPackage) {
+    /** The time of calling executeAppFunction(). */
+    private final long mRequestTime;
+
+    public ExecuteAppFunctionAidlRequest(ExecuteAppFunctionRequest clientRequest,
+            UserHandle userHandle, String callingPackage, long requestTime) {
         this.mClientRequest = Objects.requireNonNull(clientRequest);
         this.mUserHandle = Objects.requireNonNull(userHandle);
         this.mCallingPackage = Objects.requireNonNull(callingPackage);
+        this.mRequestTime = requestTime;
     }
 
     @Override
@@ -77,6 +82,7 @@
         mClientRequest.writeToParcel(dest, flags);
         mUserHandle.writeToParcel(dest, flags);
         dest.writeString8(mCallingPackage);
+        dest.writeLong(mRequestTime);
     }
 
     /** Returns the client request to execute an app function. */
@@ -96,4 +102,9 @@
     public String getCallingPackage() {
         return mCallingPackage;
     }
+
+    /** Returns the time of calling executeAppFunction(). */
+    public long getRequestTime() {
+        return mRequestTime;
+    }
 }
diff --git a/core/java/android/app/appfunctions/SafeOneTimeExecuteAppFunctionCallback.java b/core/java/android/app/appfunctions/SafeOneTimeExecuteAppFunctionCallback.java
index 2426daf..e527de2 100644
--- a/core/java/android/app/appfunctions/SafeOneTimeExecuteAppFunctionCallback.java
+++ b/core/java/android/app/appfunctions/SafeOneTimeExecuteAppFunctionCallback.java
@@ -17,11 +17,14 @@
 package android.app.appfunctions;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.util.Log;
 
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
 
 /**
  * A wrapper of IExecuteAppFunctionCallback which swallows the {@link RemoteException}. This
@@ -37,8 +40,19 @@
 
     @NonNull private final IExecuteAppFunctionCallback mCallback;
 
+    @Nullable
+    private final CompletionCallback mCompletionCallback;
+
+    private final AtomicLong mExecutionStartTimeAfterBindMillis = new AtomicLong();
+
     public SafeOneTimeExecuteAppFunctionCallback(@NonNull IExecuteAppFunctionCallback callback) {
+        this(callback, /* completionCallback= */ null);
+    }
+
+    public SafeOneTimeExecuteAppFunctionCallback(@NonNull IExecuteAppFunctionCallback callback,
+            @Nullable CompletionCallback completionCallback) {
         mCallback = Objects.requireNonNull(callback);
+        mCompletionCallback = completionCallback;
     }
 
     /** Invoke wrapped callback with the result. */
@@ -49,6 +63,10 @@
         }
         try {
             mCallback.onSuccess(result);
+            if (mCompletionCallback != null) {
+                mCompletionCallback.finalizeOnSuccess(result,
+                        mExecutionStartTimeAfterBindMillis.get());
+            }
         } catch (RemoteException ex) {
             // Failed to notify the other end. Ignore.
             Log.w(TAG, "Failed to invoke the callback", ex);
@@ -63,6 +81,10 @@
         }
         try {
             mCallback.onError(error);
+            if (mCompletionCallback != null) {
+                mCompletionCallback.finalizeOnError(error,
+                        mExecutionStartTimeAfterBindMillis.get());
+            }
         } catch (RemoteException ex) {
             // Failed to notify the other end. Ignore.
             Log.w(TAG, "Failed to invoke the callback", ex);
@@ -76,4 +98,27 @@
     public void disable() {
         mOnResultCalled.set(true);
     }
+
+    /**
+     * Sets the execution start time of the request. Used to calculate the overhead latency of
+     * requests.
+     */
+    public void setExecutionStartTimeMillis() {
+        if (!mExecutionStartTimeAfterBindMillis.compareAndSet(0, SystemClock.elapsedRealtime())) {
+            Log.w(TAG, "Ignore subsequent calls to setExecutionStartTimeMillis()");
+        }
+    }
+
+    /**
+     * Provides a hook to execute additional actions after the {@link IExecuteAppFunctionCallback}
+     * has been invoked.
+     */
+    public interface CompletionCallback {
+        /** Called after {@link IExecuteAppFunctionCallback#onSuccess}. */
+        void finalizeOnSuccess(@NonNull ExecuteAppFunctionResponse result,
+                long executionStartTimeMillis);
+
+        /** Called after {@link IExecuteAppFunctionCallback#onError}. */
+        void finalizeOnError(@NonNull AppFunctionException error, long executionStartTimeMillis);
+    }
 }
diff --git a/core/java/android/app/jank/JankDataProcessor.java b/core/java/android/app/jank/JankDataProcessor.java
index 7ceaeb3..c947259 100644
--- a/core/java/android/app/jank/JankDataProcessor.java
+++ b/core/java/android/app/jank/JankDataProcessor.java
@@ -215,7 +215,8 @@
 
         try {
             mPendingJankStats.values().forEach(stat -> {
-                        FrameworkStatsLog.write(FrameworkStatsLog.JANK_FRAME_COUNT_BY_WIDGET,
+                        FrameworkStatsLog.write(
+                                FrameworkStatsLog.JANK_FRAME_COUNT_BY_WIDGET_REPORTED,
                                 /*app uid*/ stat.getUid(),
                                 /*activity name*/ stat.getActivityName(),
                                 /*widget id*/ stat.getWidgetId(),
diff --git a/core/java/android/app/jank/JankTracker.java b/core/java/android/app/jank/JankTracker.java
index 4695216..a04f96a 100644
--- a/core/java/android/app/jank/JankTracker.java
+++ b/core/java/android/app/jank/JankTracker.java
@@ -29,6 +29,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 
 /**
  * This class is responsible for registering callbacks that will receive JankData batches.
@@ -174,6 +175,15 @@
     }
 
     /**
+     * Retrieve all pending jank stats before they are logged, this is intended for testing
+     * purposes only.
+     */
+    @VisibleForTesting
+    public HashMap<String, JankDataProcessor.PendingJankStat> getPendingJankStats() {
+        return mJankDataProcessor.getPendingJankStats();
+    }
+
+    /**
      * Only intended to be used by tests, the runnable that registers the listeners may not run
      * in time for tests to pass. This forces them to run immediately.
      */
@@ -192,7 +202,11 @@
          */
     }
 
-    private boolean shouldTrack() {
+    /**
+     * Returns whether jank tracking is enabled or not.
+     */
+    @VisibleForTesting
+    public boolean shouldTrack() {
         return mTrackingEnabled && mListenersRegistered;
     }
 
diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig
index 7543fa9..b1db137 100644
--- a/core/java/android/app/notification.aconfig
+++ b/core/java/android/app/notification.aconfig
@@ -291,6 +291,13 @@
 }
 
 flag {
+  name: "nm_binder_perf_throttle_notify"
+  namespace: "systemui"
+  description: "Rate-limit calls to enqueueNotificationWithTag client-side"
+  bug: "362981561"
+}
+
+flag {
   name: "no_sbnholder"
   namespace: "systemui"
   description: "removes sbnholder from NLS"
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 40de298..67ad459 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -37,36 +37,44 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.Intent.FilterComparison;
 import android.content.IntentSender;
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ShortcutInfo;
 import android.graphics.Rect;
+import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerExecutor;
 import android.os.HandlerThread;
+import android.os.IBinder;
 import android.os.Looper;
 import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.util.ArrayMap;
 import android.util.DisplayMetrics;
 import android.util.Log;
+import android.util.Pair;
 import android.widget.RemoteViews;
 
 import com.android.internal.appwidget.IAppWidgetService;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.FunctionalUtils;
 
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executor;
+import java.util.function.Consumer;
 
 /**
  * Updates AppWidget state; gets information about installed AppWidget providers and other
@@ -592,6 +600,8 @@
 
     private boolean mHasPostedLegacyLists = false;
 
+    private @NonNull ServiceCollectionCache mServiceCollectionCache;
+
     /**
      * Get the AppWidgetManager instance to use for the supplied {@link android.content.Context
      * Context} object.
@@ -612,6 +622,7 @@
         mPackageName = context.getOpPackageName();
         mService = service;
         mDisplayMetrics = context.getResources().getDisplayMetrics();
+        mServiceCollectionCache = new ServiceCollectionCache(context, /* timeout= */ 5000L);
         if (mService == null) {
             return;
         }
@@ -649,7 +660,7 @@
             final RemoteViews viewsCopy = new RemoteViews(original);
             Runnable updateWidgetWithTask = () -> {
                 try {
-                    viewsCopy.collectAllIntents(mMaxBitmapMemory).get();
+                    viewsCopy.collectAllIntents(mMaxBitmapMemory, mServiceCollectionCache).get();
                     action.acceptOrThrow(viewsCopy);
                 } catch (Exception e) {
                     Log.e(TAG, failureMsg, e);
@@ -1629,4 +1640,106 @@
         thread.start();
         return thread.getThreadHandler();
     }
+
+    /**
+     * @hide
+     */
+    public static class ServiceCollectionCache {
+
+        private final Context mContext;
+        private final Handler mHandler;
+        private final long mTimeOut;
+
+        private final Map<FilterComparison, ConnectionTask> mActiveConnections =
+                new ArrayMap<>();
+
+        public ServiceCollectionCache(Context context, long timeOut) {
+            mContext = context;
+            mHandler = new Handler(BackgroundThread.getHandler().getLooper());
+            mTimeOut = timeOut;
+        }
+
+        /**
+         * Connect to the service indicated by the {@code Intent}, and consume the binder on the
+         * specified executor
+         */
+        public void connectAndConsume(Intent intent, Consumer<IBinder> task, Executor executor) {
+            mHandler.post(() -> connectAndConsumeInner(intent, task, executor));
+        }
+
+        private void connectAndConsumeInner(Intent intent, Consumer<IBinder> task,
+                Executor executor) {
+            ConnectionTask activeConnection = mActiveConnections.computeIfAbsent(
+                    new FilterComparison(intent), ConnectionTask::new);
+            activeConnection.add(task, executor);
+        }
+
+        private class ConnectionTask implements ServiceConnection {
+
+            private final Runnable mDestroyAfterTimeout = this::onDestroyTimeout;
+            private final ArrayDeque<Pair<Consumer<IBinder>, Executor>> mTaskQueue =
+                    new ArrayDeque<>();
+
+            private boolean mOnDestroyTimeout = false;
+            private IBinder mIBinder;
+
+            ConnectionTask(@NonNull FilterComparison filter) {
+                mContext.bindService(filter.getIntent(),
+                        Context.BindServiceFlags.of(Context.BIND_AUTO_CREATE),
+                        mHandler::post,
+                        this);
+            }
+
+            @Override
+            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
+                mIBinder = iBinder;
+                mHandler.post(this::handleNext);
+            }
+
+            @Override
+            public void onNullBinding(ComponentName name) {
+                // Use an empty binder, follow up tasks will handle the failure
+                onServiceConnected(name, new Binder());
+            }
+
+            @Override
+            public void onServiceDisconnected(ComponentName componentName) { }
+
+            void add(Consumer<IBinder> task, Executor executor) {
+                mTaskQueue.add(Pair.create(task, executor));
+                if (mOnDestroyTimeout) {
+                    // If we are waiting for timeout, cancel it and execute the next task
+                    handleNext();
+                }
+            }
+
+            private void handleNext() {
+                mHandler.removeCallbacks(mDestroyAfterTimeout);
+                Pair<Consumer<IBinder>, Executor> next = mTaskQueue.pollFirst();
+                if (next != null) {
+                    mOnDestroyTimeout = false;
+                    next.second.execute(() -> {
+                        next.first.accept(mIBinder);
+                        mHandler.post(this::handleNext);
+                    });
+                } else {
+                    // Finished all tasks, start a timeout to unbind this service
+                    mOnDestroyTimeout = true;
+                    mHandler.postDelayed(mDestroyAfterTimeout, mTimeOut);
+                }
+            }
+
+            /**
+             * Called after we have waited for {@link #mTimeOut} after the last task is finished
+             */
+            private void onDestroyTimeout() {
+                if (!mTaskQueue.isEmpty()) {
+                    handleNext();
+                    return;
+                }
+                mContext.unbindService(this);
+                mActiveConnections.values().remove(this);
+            }
+        }
+    }
 }
diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java
index f368935..32cbf32 100644
--- a/core/java/android/companion/AssociationRequest.java
+++ b/core/java/android/companion/AssociationRequest.java
@@ -90,9 +90,9 @@
     public static final String DEVICE_PROFILE_GLASSES = "android.app.role.COMPANION_DEVICE_GLASSES";
 
     /**
-     * Device profile: a virtual display capable of rendering Android applications, and sending back
+     * Device profile: a virtual device capable of rendering Android applications, and sending back
      * input events.
-     *
+     * <p>
      * Only applications that have been granted
      * {@link android.Manifest.permission#REQUEST_COMPANION_PROFILE_APP_STREAMING} are allowed to
      * request to be associated with such devices.
@@ -106,7 +106,7 @@
     /**
      * Device profile: a virtual device capable of rendering content from an Android host to a
      * nearby device.
-     *
+     * <p>
      * Only applications that have been granted
      * {@link android.Manifest.permission#REQUEST_COMPANION_PROFILE_NEARBY_DEVICE_STREAMING}
      * are allowed to request to be associated with such devices.
@@ -118,6 +118,21 @@
             "android.app.role.COMPANION_DEVICE_NEARBY_DEVICE_STREAMING";
 
     /**
+     * Device profile: a virtual device capable of streaming sensor data such as camera, audio and
+     * IMU between an Android host and a nearby device.
+     * <p>
+     * Only applications that have been granted
+     * {@link android.Manifest.permission#REQUEST_COMPANION_PROFILE_SENSOR_DEVICE_STREAMING}
+     * are allowed to request to be associated with such devices.
+     *
+     * @see AssociationRequest.Builder#setDeviceProfile
+     */
+    @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ENABLE_LIMITED_VDM_ROLE)
+    @RequiresPermission(Manifest.permission.REQUEST_COMPANION_PROFILE_SENSOR_DEVICE_STREAMING)
+    public static final String DEVICE_PROFILE_SENSOR_DEVICE_STREAMING =
+            "android.app.role.COMPANION_DEVICE_SENSOR_DEVICE_STREAMING";
+
+    /**
      * Device profile: Android Automotive Projection
      *
      * Only applications that have been granted
diff --git a/core/java/android/companion/DeviceId.java b/core/java/android/companion/DeviceId.java
index d9514a0..2f19eb4 100644
--- a/core/java/android/companion/DeviceId.java
+++ b/core/java/android/companion/DeviceId.java
@@ -22,7 +22,6 @@
 import android.net.MacAddress;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.provider.OneTimeUseBuilder;
 
 import java.util.Locale;
 import java.util.Objects;
@@ -159,7 +158,7 @@
      * the device: a custom ID using {@link #setCustomId(String)}, or a MAC address using
      * {@link #setMacAddress(MacAddress)}.</p>
      */
-    public static final class Builder extends OneTimeUseBuilder<DeviceId> {
+    public static final class Builder {
         private String mCustomId;
         private MacAddress mMacAddress;
 
@@ -175,7 +174,6 @@
          */
         @NonNull
         public Builder setCustomId(@Nullable String customId) {
-            checkNotUsed();
             if (customId != null
                     && customId.length() > CUSTOM_ID_LENGTH_LIMIT) {
                 throw new IllegalArgumentException("Length of the custom id must be at most "
@@ -195,15 +193,12 @@
          */
         @NonNull
         public Builder setMacAddress(@Nullable MacAddress macAddress) {
-            checkNotUsed();
             mMacAddress = macAddress;
             return this;
         }
 
         @NonNull
-        @Override
         public DeviceId build() {
-            markUsed();
             if (mCustomId == null && mMacAddress == null) {
                 throw new IllegalArgumentException("At least one device id property must be"
                         + "non-null to build a DeviceId.");
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index b3f09a9..ed2fd99 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -1290,7 +1290,11 @@
                 @NonNull UserHandle user) {}
 
         /**
-         * Called when a window with a secure surface is no longer shown on the device.
+         * Called when there is no longer any window with a secure surface shown on the device.
+         *
+         * <p>This is only called once there are no more secure windows shown on the device. If
+         * there are multiple secure windows shown on the device, this callback will be called only
+         * once all of them are hidden.</p>
          *
          * @param displayId The display ID on which the window was shown before.
          *
diff --git a/core/java/android/companion/virtualnative/IVirtualDeviceManagerNative.aidl b/core/java/android/companion/virtualnative/IVirtualDeviceManagerNative.aidl
index 5a13255..78f8ab4 100644
--- a/core/java/android/companion/virtualnative/IVirtualDeviceManagerNative.aidl
+++ b/core/java/android/companion/virtualnative/IVirtualDeviceManagerNative.aidl
@@ -64,4 +64,9 @@
      * Returns the device policy for the given virtual device and policy type.
      */
     int getDevicePolicy(int deviceId, int policyType);
+
+    /**
+     * Returns the ID of the device which owns the display with the given ID.
+     */
+    int getDeviceIdForDisplayId(int displayId);
 }
diff --git a/core/java/android/content/EventLogTags.logtags b/core/java/android/content/EventLogTags.logtags
index 21ea90a..861a5b7 100644
--- a/core/java/android/content/EventLogTags.logtags
+++ b/core/java/android/content/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
 
 option java_package android.content;
 
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index a6492d3..3d75423 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -12291,7 +12291,6 @@
         private IBinder mCreatorToken;
         // Stores all extra keys whose values are intents for a top level intent.
         private ArraySet<NestedIntentKey> mNestedIntentKeys;
-
     }
 
     /**
@@ -12353,6 +12352,7 @@
         public int hashCode() {
             return Objects.hash(mType, mKey, mIndex);
         }
+
     }
 
     private @Nullable CreatorTokenInfo mCreatorTokenInfo;
@@ -12416,7 +12416,7 @@
                     // removeLaunchSecurityProtection() is called before it is launched.
                     value = null;
                 }
-                if (value instanceof Intent intent && !visited.contains(intent)) {
+                if (value instanceof Intent intent) {
                     handleNestedIntent(intent, visited, new NestedIntentKey(
                             NestedIntentKey.NESTED_INTENT_KEY_TYPE_EXTRA_PARCEL, key, 0));
                 } else if (value instanceof Parcelable[] parcelables) {
@@ -12439,7 +12439,6 @@
     }
 
     private void handleNestedIntent(Intent intent, Set<Intent> visited, NestedIntentKey key) {
-        visited.add(intent);
         if (mCreatorTokenInfo == null) {
             mCreatorTokenInfo = new CreatorTokenInfo();
         }
@@ -12447,7 +12446,10 @@
             mCreatorTokenInfo.mNestedIntentKeys = new ArraySet<>();
         }
         mCreatorTokenInfo.mNestedIntentKeys.add(key);
-        intent.collectNestedIntentKeysRecur(visited);
+        if (!visited.contains(intent)) {
+            visited.add(intent);
+            intent.collectNestedIntentKeysRecur(visited);
+        }
     }
 
     private void handleParcelableArray(Parcelable[] parcelables, String key, Set<Intent> visited) {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 7e08051..9992d58 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -12023,11 +12023,8 @@
      * file.
      *
      * @throws SigningInfoException if the verification fails
-     *
-     * @hide
      */
     @FlaggedApi(android.content.pm.Flags.FLAG_CLOUD_COMPILATION_PM)
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static @NonNull SigningInfo getVerifiedSigningInfo(@NonNull String path,
             @AppSigningSchemeVersion int minAppSigningSchemeVersion) throws SigningInfoException {
         ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
diff --git a/core/java/android/content/pm/SigningInfo.java b/core/java/android/content/pm/SigningInfo.java
index e4fbd1f..21bbb0a 100644
--- a/core/java/android/content/pm/SigningInfo.java
+++ b/core/java/android/content/pm/SigningInfo.java
@@ -22,7 +22,6 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 import android.content.pm.SigningDetails.SignatureSchemeVersion;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -40,41 +39,29 @@
     /**
      * JAR signing (v1 scheme).
      * See https://source.android.com/docs/security/features/apksigning#v1.
-     *
-     * @hide
      */
     @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int VERSION_JAR = SignatureSchemeVersion.JAR;
 
     /**
      * APK signature scheme v2.
      * See https://source.android.com/docs/security/features/apksigning/v2.
-     *
-     * @hide
      */
     @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int VERSION_SIGNING_BLOCK_V2 = SignatureSchemeVersion.SIGNING_BLOCK_V2;
 
     /**
      * APK signature scheme v3.
      * See https://source.android.com/docs/security/features/apksigning/v3.
-     *
-     * @hide
      */
     @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int VERSION_SIGNING_BLOCK_V3 = SignatureSchemeVersion.SIGNING_BLOCK_V3;
 
     /**
      * APK signature scheme v4.
      * See https://source.android.com/docs/security/features/apksigning/v4.
-     *
-     * @hide
      */
     @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int VERSION_SIGNING_BLOCK_V4 = SignatureSchemeVersion.SIGNING_BLOCK_V4;
 
     /** @hide */
@@ -255,11 +242,8 @@
 
     /**
      * Returns true if the signing certificates in this and other match exactly.
-     *
-     * @hide
      */
     @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public boolean signersMatchExactly(@NonNull SigningInfo other) {
         return mSigningDetails.signaturesMatchExactly(other.mSigningDetails);
     }
diff --git a/core/java/android/content/pm/SigningInfoException.java b/core/java/android/content/pm/SigningInfoException.java
index a81e07e..2fd1bfb 100644
--- a/core/java/android/content/pm/SigningInfoException.java
+++ b/core/java/android/content/pm/SigningInfoException.java
@@ -19,17 +19,13 @@
 import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 
 /**
  * Indicates an error when verifying the
  * <a href="https://source.android.com/docs/security/features/apksigning">app signing</a>
  * information.
- *
- * @hide
  */
 @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
 public class SigningInfoException extends Exception {
     private final int mCode;
 
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index dfeee2a..00ddae3 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -362,3 +362,9 @@
     is_fixed_read_only: true
 }
 
+flag {
+    name: "remove_hidden_module_usage"
+    namespace: "modularization"
+    description: "Feature flag to remove the consumption of the hidden module status (ModuleInfo#IsHidden) in the Android source tree."
+    bug: "363952383"
+}
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 18a45d8d..5381301 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -539,9 +539,6 @@
                                     hasBindDeviceAdminPermission);
                             break;
                         case TAG_USES_SDK_LIBRARY:
-                            if (!android.content.pm.Flags.sdkDependencyInstaller()) {
-                                break;
-                            }
                             String usesSdkLibName = parser.getAttributeValue(
                                     ANDROID_RES_NAMESPACE, "name");
                             // TODO(b/379219371): Due to a bug in bundletool, some apps can use
diff --git a/core/java/android/content/res/flags.aconfig b/core/java/android/content/res/flags.aconfig
index 6fc7d90..ecb4bb1 100644
--- a/core/java/android/content/res/flags.aconfig
+++ b/core/java/android/content/res/flags.aconfig
@@ -114,3 +114,11 @@
     bug: "373535266"
     is_fixed_read_only: true
 }
+
+flag {
+    name: "self_targeting_android_resource_frro"
+    is_exported: true
+    namespace: "customization_picker"
+    description: "Fixes bug in Launcher preview by enabling overlays targeting 'android'"
+    bug: "377545987"
+}
\ No newline at end of file
diff --git a/core/java/android/content/res/loader/ResourcesProvider.java b/core/java/android/content/res/loader/ResourcesProvider.java
index 830b7e0..7eba181 100644
--- a/core/java/android/content/res/loader/ResourcesProvider.java
+++ b/core/java/android/content/res/loader/ResourcesProvider.java
@@ -25,6 +25,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.res.ApkAssets;
 import android.content.res.AssetFileDescriptor;
+import android.content.res.Flags;
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
@@ -90,6 +91,10 @@
             throws IOException {
         Objects.requireNonNull(overlayInfo);
         Preconditions.checkArgument(overlayInfo.isFabricated(), "Not accepted overlay");
+        if (!Flags.selfTargetingAndroidResourceFrro()) {
+            Preconditions.checkStringNotEmpty(
+                    overlayInfo.getTargetOverlayableName(), "Without overlayable name");
+        }
         final String overlayName =
                 OverlayManagerImpl.checkOverlayNameValid(overlayInfo.getOverlayName());
         final String path =
diff --git a/core/java/android/credentials/flags.aconfig b/core/java/android/credentials/flags.aconfig
index d8d4e16..9c811fb 100644
--- a/core/java/android/credentials/flags.aconfig
+++ b/core/java/android/credentials/flags.aconfig
@@ -124,3 +124,13 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    namespace: "credential_manager"
+    name: "settings_w_fixes"
+    description: "Settings improvements for credential manager"
+    bug: "373711451"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/core/java/android/credentials/selection/IntentFactory.java b/core/java/android/credentials/selection/IntentFactory.java
index c521b96..59539c4 100644
--- a/core/java/android/credentials/selection/IntentFactory.java
+++ b/core/java/android/credentials/selection/IntentFactory.java
@@ -16,7 +16,7 @@
 
 package android.credentials.selection;
 
-import static android.credentials.flags.Flags.FLAG_CONFIGURABLE_SELECTOR_UI_ENABLED;
+import static android.credentials.flags.Flags.FLAG_PROPAGATE_USER_CONTEXT_FOR_INTENT_CREATION;
 import static android.credentials.flags.Flags.configurableSelectorUiEnabled;
 
 import android.annotation.FlaggedApi;
@@ -24,6 +24,8 @@
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.annotation.TestApi;
+import android.annotation.UserIdInt;
+import android.app.AppGlobals;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -32,6 +34,7 @@
 import android.content.res.Resources;
 import android.os.IBinder;
 import android.os.Parcel;
+import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.text.TextUtils;
 import android.util.Slog;
@@ -46,7 +49,7 @@
  * @hide
  */
 @TestApi
-@FlaggedApi(FLAG_CONFIGURABLE_SELECTOR_UI_ENABLED)
+@FlaggedApi(FLAG_PROPAGATE_USER_CONTEXT_FOR_INTENT_CREATION)
 public class IntentFactory {
 
     /**
@@ -65,9 +68,10 @@
             @SuppressLint("ConcreteCollection") // Concrete collection needed for marshalling.
             @NonNull
             ArrayList<DisabledProviderData> disabledProviderDataList,
-            @NonNull ResultReceiver resultReceiver) {
+            @NonNull ResultReceiver resultReceiver,
+            @UserIdInt int userId) {
         return createCredentialSelectorIntentInternal(context, requestInfo,
-                disabledProviderDataList, resultReceiver);
+                disabledProviderDataList, resultReceiver, userId);
     }
 
     /**
@@ -96,9 +100,10 @@
             @SuppressLint("ConcreteCollection") // Concrete collection needed for marshalling.
             @NonNull
             ArrayList<DisabledProviderData> disabledProviderDataList,
-            @NonNull ResultReceiver resultReceiver) {
+            @NonNull ResultReceiver resultReceiver,
+            @UserIdInt int userId) {
         IntentCreationResult result = createCredentialSelectorIntentInternal(context, requestInfo,
-                disabledProviderDataList, resultReceiver);
+                disabledProviderDataList, resultReceiver, userId);
         result.getIntent().putParcelableArrayListExtra(
                 ProviderData.EXTRA_ENABLED_PROVIDER_DATA_LIST, enabledProviderDataList);
         return result;
@@ -130,9 +135,10 @@
             @SuppressLint("ConcreteCollection") // Concrete collection needed for marshalling.
             @NonNull
             ArrayList<DisabledProviderData> disabledProviderDataList,
-            @NonNull ResultReceiver resultReceiver) {
+            @NonNull ResultReceiver resultReceiver, @UserIdInt int userId) {
         return createCredentialSelectorIntentForCredMan(context, requestInfo,
-                enabledProviderDataList, disabledProviderDataList, resultReceiver).getIntent();
+            enabledProviderDataList, disabledProviderDataList, resultReceiver,
+            userId).getIntent();
     }
 
     /**
@@ -142,10 +148,10 @@
     @NonNull
     public static Intent createCancelUiIntent(@NonNull Context context,
             @NonNull IBinder requestToken, boolean shouldShowCancellationUi,
-            @NonNull String appPackageName) {
+            @NonNull String appPackageName, @UserIdInt int userId) {
         Intent intent = new Intent();
         IntentCreationResult.Builder intentResultBuilder = new IntentCreationResult.Builder(intent);
-        setCredentialSelectorUiComponentName(context, intent, intentResultBuilder);
+        setCredentialSelectorUiComponentName(context, intent, intentResultBuilder, userId);
         intent.putExtra(CancelSelectionRequest.EXTRA_CANCEL_UI_REQUEST,
                 new CancelSelectionRequest(new RequestToken(requestToken), shouldShowCancellationUi,
                         appPackageName));
@@ -162,10 +168,10 @@
             @SuppressLint("ConcreteCollection") // Concrete collection needed for marshalling.
             @NonNull
             ArrayList<DisabledProviderData> disabledProviderDataList,
-            @NonNull ResultReceiver resultReceiver) {
+            @NonNull ResultReceiver resultReceiver, @UserIdInt int userId) {
         Intent intent = new Intent();
         IntentCreationResult.Builder intentResultBuilder = new IntentCreationResult.Builder(intent);
-        setCredentialSelectorUiComponentName(context, intent, intentResultBuilder);
+        setCredentialSelectorUiComponentName(context, intent, intentResultBuilder, userId);
         intent.putParcelableArrayListExtra(
                 ProviderData.EXTRA_DISABLED_PROVIDER_DATA_LIST, disabledProviderDataList);
         intent.putExtra(RequestInfo.EXTRA_REQUEST_INFO, requestInfo);
@@ -175,9 +181,11 @@
     }
 
     private static void setCredentialSelectorUiComponentName(@NonNull Context context,
-            @NonNull Intent intent, @NonNull IntentCreationResult.Builder intentResultBuilder) {
+            @NonNull Intent intent, @NonNull IntentCreationResult.Builder intentResultBuilder,
+            @UserIdInt int userId) {
         if (configurableSelectorUiEnabled()) {
-            ComponentName componentName = getOemOverrideComponentName(context, intentResultBuilder);
+            ComponentName componentName = getOemOverrideComponentName(context,
+                    intentResultBuilder, userId);
 
             ComponentName fallbackUiComponentName = null;
             try {
@@ -210,7 +218,7 @@
      */
     @Nullable
     private static ComponentName getOemOverrideComponentName(@NonNull Context context,
-            @NonNull IntentCreationResult.Builder intentResultBuilder) {
+            @NonNull IntentCreationResult.Builder intentResultBuilder, @UserIdInt int userId) {
         ComponentName result = null;
         String oemComponentString =
                 Resources.getSystem()
@@ -228,35 +236,43 @@
             if (oemComponentName != null) {
                 try {
                     intentResultBuilder.setOemUiPackageName(oemComponentName.getPackageName());
-                    ActivityInfo info = context.getPackageManager().getActivityInfo(
-                            oemComponentName,
-                            PackageManager.ComponentInfoFlags.of(
-                                    PackageManager.MATCH_SYSTEM_ONLY));
-                    boolean oemComponentEnabled = info.enabled;
-                    int runtimeComponentEnabledState = context.getPackageManager()
+                    ActivityInfo info;
+                    if (android.credentials.flags.Flags.propagateUserContextForIntentCreation()) {
+                      info = context.getPackageManager().getActivityInfo(oemComponentName,
+                          PackageManager.ComponentInfoFlags.of(
+                              PackageManager.MATCH_SYSTEM_ONLY));
+                    } else {
+                      info = AppGlobals.getPackageManager().getActivityInfo(
+                          oemComponentName, 0, userId);
+                    }
+                    boolean oemComponentEnabled = false;
+                    if (info != null) {
+                      oemComponentEnabled = info.enabled;
+                      int runtimeComponentEnabledState = context.getPackageManager()
                           .getComponentEnabledSetting(oemComponentName);
-                    if (runtimeComponentEnabledState == PackageManager
+                      if (runtimeComponentEnabledState == PackageManager
                           .COMPONENT_ENABLED_STATE_ENABLED) {
-                          oemComponentEnabled = true;
-                    } else if (runtimeComponentEnabledState == PackageManager
+                        oemComponentEnabled = true;
+                      } else if (runtimeComponentEnabledState == PackageManager
                           .COMPONENT_ENABLED_STATE_DISABLED) {
                         oemComponentEnabled = false;
-                    }
-                    if (oemComponentEnabled && info.exported) {
+                      }
+                      if (oemComponentEnabled && info.exported) {
                         intentResultBuilder.setOemUiUsageStatus(IntentCreationResult
-                                .OemUiUsageStatus.SUCCESS);
+                            .OemUiUsageStatus.SUCCESS);
                         Slog.i(TAG,
-                                "Found enabled oem CredMan UI component."
-                                        + oemComponentString);
+                            "Found enabled oem CredMan UI component."
+                                + oemComponentString);
                         result = oemComponentName;
-                    } else {
-                        intentResultBuilder.setOemUiUsageStatus(IntentCreationResult
-                                .OemUiUsageStatus.OEM_UI_CONFIG_SPECIFIED_FOUND_BUT_NOT_ENABLED);
-                        Slog.i(TAG,
-                                "Found enabled oem CredMan UI component but it was not "
-                                        + "enabled.");
+                      } else {
+                          intentResultBuilder.setOemUiUsageStatus(IntentCreationResult
+                                  .OemUiUsageStatus.OEM_UI_CONFIG_SPECIFIED_FOUND_BUT_NOT_ENABLED);
+                          Slog.i(TAG,
+                                  "Found enabled oem CredMan UI component but it was not "
+                                      + "enabled.");
+                      }
                     }
-                } catch (PackageManager.NameNotFoundException e) {
+                } catch (RemoteException | PackageManager.NameNotFoundException e) {
                     intentResultBuilder.setOemUiUsageStatus(IntentCreationResult.OemUiUsageStatus
                             .OEM_UI_CONFIG_SPECIFIED_BUT_NOT_FOUND);
                     Slog.i(TAG, "Unable to find oem CredMan UI component: "
diff --git a/core/java/android/database/sqlite/SQLiteRawStatement.java b/core/java/android/database/sqlite/SQLiteRawStatement.java
index c59d3ce..ce2334a 100644
--- a/core/java/android/database/sqlite/SQLiteRawStatement.java
+++ b/core/java/android/database/sqlite/SQLiteRawStatement.java
@@ -533,11 +533,11 @@
     }
 
     /**
-     * Return the number of columns in the current result row.
+     * Return the number of columns in the result set for the statement.
      *
      * @see <a href="http://sqlite.org/c3ref/column_count.html">sqlite3_column_count</a>
      *
-     * @return The number of columns in the result row.
+     * @return The number of columns in the result set.
      * @throws IllegalStateException if the statement is closed or this is a foreign thread.
      */
     public int getResultColumnCount() {
@@ -554,10 +554,16 @@
      *
      * @see <a href="http://sqlite.org/c3ref/column_blob.html">sqlite3_column_type</a>
      *
+     * If the row has no data then a {@link SQLiteMisuseException} is thrown.  This condition can
+     * occur the last call to {@link #step()} returned false or if {@link #step()} was not called
+     * before the statement was created or after the last call to {@link #reset()}.  Note that
+     * {@link SQLiteMisuseException} may be thrown for other reasons.
+     *
      * @param columnIndex The index of a column in the result row. It is zero-based.
      * @return The type of the value in the column of the result row.
      * @throws IllegalStateException if the statement is closed or this is a foreign thread.
      * @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+     * @throws SQLiteMisuseException if the row has no data.
      * @throws SQLiteException if a native error occurs.
      */
     @SQLiteDataType
@@ -580,6 +586,7 @@
      * @return The name of the column in the result row.
      * @throws IllegalStateException if the statement is closed or this is a foreign thread.
      * @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+     * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
      * @throws SQLiteOutOfMemoryException if the database cannot allocate memory for the name.
      */
     @NonNull
@@ -606,6 +613,7 @@
      * @return The length, in bytes, of the value in the column.
      * @throws IllegalStateException if the statement is closed or this is a foreign thread.
      * @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+     * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
      * @throws SQLiteException if a native error occurs.
      */
     public int getColumnLength(int columnIndex) {
@@ -631,6 +639,7 @@
      * @return The value of the column as a blob, or null if the column is NULL.
      * @throws IllegalStateException if the statement is closed or this is a foreign thread.
      * @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+     * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
      * @throws SQLiteException if a native error occurs.
      */
     @Nullable
@@ -664,6 +673,7 @@
      * @throws IllegalStateException if the statement is closed or this is a foreign thread.
      * @throws IllegalArgumentException if the buffer is too small for offset+length.
      * @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+     * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
      * @throws SQLiteException if a native error occurs.
      */
     public int readColumnBlob(int columnIndex, @NonNull byte[] buffer, int offset,
@@ -691,6 +701,7 @@
      * @return The value of a column as a double.
      * @throws IllegalStateException if the statement is closed or this is a foreign thread.
      * @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+     * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
      * @throws SQLiteException if a native error occurs.
      */
     public double getColumnDouble(int columnIndex) {
@@ -715,6 +726,7 @@
      * @return The value of the column as an int.
      * @throws IllegalStateException if the statement is closed or this is a foreign thread.
      * @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+     * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
      * @throws SQLiteException if a native error occurs.
      */
     public int getColumnInt(int columnIndex) {
@@ -739,6 +751,7 @@
      * @return The value of the column as an long.
      * @throws IllegalStateException if the statement is closed or this is a foreign thread.
      * @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+     * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
      * @throws SQLiteException if a native error occurs.
      */
     public long getColumnLong(int columnIndex) {
@@ -763,6 +776,7 @@
      * @return The value of the column as a string.
      * @throws IllegalStateException if the statement is closed or this is a foreign thread.
      * @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+     * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
      * @throws SQLiteException if a native error occurs.
      */
     @NonNull
diff --git a/core/java/android/hardware/contexthub/HubEndpoint.java b/core/java/android/hardware/contexthub/HubEndpoint.java
index 1f12bbf..b251aa1 100644
--- a/core/java/android/hardware/contexthub/HubEndpoint.java
+++ b/core/java/android/hardware/contexthub/HubEndpoint.java
@@ -66,13 +66,14 @@
                 REASON_CLOSE_ENDPOINT_SESSION_REQUESTED,
                 REASON_ENDPOINT_INVALID,
                 REASON_ENDPOINT_STOPPED,
+                REASON_PERMISSION_DENIED,
             })
     public @interface Reason {}
 
     /** Unclassified failure */
     public static final int REASON_FAILURE = 0;
 
-    // The values 1 and 2 are reserved at the Context Hub HAL but not exposed to apps.
+    // The values 1-2 are reserved at the Context Hub HAL but not exposed to apps.
 
     /** The peer rejected the request to open this endpoint session. */
     public static final int REASON_OPEN_ENDPOINT_SESSION_REQUEST_REJECTED = 3;
@@ -83,6 +84,11 @@
     /** The peer endpoint is invalid. */
     public static final int REASON_ENDPOINT_INVALID = 5;
 
+    // The values 6-8 are reserved at the Context Hub HAL but not exposed to apps.
+
+    /** The endpoint did not have the required permissions. */
+    public static final int REASON_PERMISSION_DENIED = 9;
+
     /**
      * The endpoint is now stopped. The app should retrieve the endpoint info using {@link
      * android.hardware.location.ContextHubManager#findEndpoints} or register updates through
@@ -349,7 +355,10 @@
         }
         try {
             IContextHubEndpoint serviceToken =
-                    service.registerEndpoint(mPendingHubEndpointInfo, mServiceCallback);
+                    service.registerEndpoint(
+                            mPendingHubEndpointInfo,
+                            mServiceCallback,
+                            mPendingHubEndpointInfo.getTag());
             mAssignedHubEndpointInfo = serviceToken.getAssignedHubEndpointInfo();
             mServiceToken = serviceToken;
         } catch (RemoteException e) {
diff --git a/core/java/android/hardware/display/DisplayTopology.java b/core/java/android/hardware/display/DisplayTopology.java
index 1f7d426..211aeff 100644
--- a/core/java/android/hardware/display/DisplayTopology.java
+++ b/core/java/android/hardware/display/DisplayTopology.java
@@ -91,6 +91,15 @@
     @VisibleForTesting
     public DisplayTopology(TreeNode root, int primaryDisplayId) {
         mRoot = root;
+        if (mRoot != null) {
+            // Set mRoot's position and offset to predictable values, just so we don't leak state
+            // from some previous arrangement the node was used in, or leak arbitrary values passed
+            // to the TreeNode constructor. The position and offset don't mean anything because
+            // mRoot doesn't have a parent.
+            mRoot.mPosition = POSITION_LEFT;
+            mRoot.mOffset = 0f;
+        }
+
         mPrimaryDisplayId = primaryDisplayId;
     }
 
@@ -422,6 +431,14 @@
                 }
             }
         }
+
+        // Sort children lists by display ID.
+        final Comparator<TreeNode> idComparator = (d1, d2) -> {
+            return Integer.compare(d1.mDisplayId, d2.mDisplayId);
+        };
+        for (TreeNode display : displays) {
+            display.mChildren.sort(idComparator);
+        }
     }
 
     /**
diff --git a/core/java/android/hardware/input/KeyGestureEvent.java b/core/java/android/hardware/input/KeyGestureEvent.java
index af756b9..47ef461 100644
--- a/core/java/android/hardware/input/KeyGestureEvent.java
+++ b/core/java/android/hardware/input/KeyGestureEvent.java
@@ -124,6 +124,7 @@
     public static final int KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION = 74;
     public static final int KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK = 75;
     public static final int KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW = 76;
+    public static final int KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB = 77;
 
 
     public static final int FLAG_CANCELLED = 1;
@@ -215,7 +216,8 @@
             KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_OUT,
             KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION,
             KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK,
-            KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW
+            KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW,
+            KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface KeyGestureType {
@@ -788,6 +790,8 @@
                 return "KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK";
             case KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW:
                 return "KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW";
+            case KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB:
+                return "KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB";
             default:
                 return Integer.toHexString(value);
         }
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
index eb7b409..aaa78aa 100644
--- a/core/java/android/hardware/input/input_framework.aconfig
+++ b/core/java/android/hardware/input/input_framework.aconfig
@@ -189,4 +189,11 @@
   namespace: "wallet_integration"
   description: "Adds new API in WindowManager class to check if the window can override the power key double tap behavior."
   bug: "378736024"
-  }
\ No newline at end of file
+  }
+
+flag {
+    name: "pointer_acceleration"
+    namespace: "input"
+    description: "Allows the user to disable pointer acceleration for mouse and touchpads."
+    bug: "349006858"
+}
\ No newline at end of file
diff --git a/core/java/android/hardware/location/IContextHubService.aidl b/core/java/android/hardware/location/IContextHubService.aidl
index f14aadc..2a47237 100644
--- a/core/java/android/hardware/location/IContextHubService.aidl
+++ b/core/java/android/hardware/location/IContextHubService.aidl
@@ -137,7 +137,7 @@
 
     // Register an endpoint with the context hub
     @EnforcePermission("ACCESS_CONTEXT_HUB")
-    IContextHubEndpoint registerEndpoint(in HubEndpointInfo pendingEndpointInfo, in IContextHubEndpointCallback callback);
+    IContextHubEndpoint registerEndpoint(in HubEndpointInfo pendingEndpointInfo, in IContextHubEndpointCallback callback, String packageName);
 
     // Register an endpoint discovery callback (id)
     @EnforcePermission("ACCESS_CONTEXT_HUB")
diff --git a/core/java/android/hardware/radio/ProgramSelector.java b/core/java/android/hardware/radio/ProgramSelector.java
index 42028f6..e5717ac 100644
--- a/core/java/android/hardware/radio/ProgramSelector.java
+++ b/core/java/android/hardware/radio/ProgramSelector.java
@@ -43,22 +43,20 @@
  *     <li>DAB channel info</li>
  * </ui>
  *
- * <p>The primary ID uniquely identifies a station and can be used for equality
- * check. The secondary IDs are supplementary and can speed up tuning process,
- * but the primary ID is sufficient (ie. after a full band scan).
- *
- * <p>Two selectors with different secondary IDs, but the same primary ID are
- * considered equal. In particular, secondary IDs vector may get updated for
+ * <p>Except for DAB radio, two selectors with different secondary IDs, but the same primary
+ * ID are considered equal. In particular, secondary IDs vector may get updated for
  * an entry on the program list (ie. when a better frequency for a given
- * station is found).
+ * station is found). For DAB radio, two selectors with the same primary ID and the same
+ * DAB frequency and DAB ensemble secondary IDs (if exist) are considered equal.
  *
  * <p>The primaryId of a given programType MUST be of a specific type:
  * <ui>
- *     <li>AM, FM: RDS_PI if the station broadcasts RDS, AMFM_FREQUENCY otherwise;</li>
- *     <li>AM_HD, FM_HD: HD_STATION_ID_EXT;</li>
- *     <li>DAB: DAB_SIDECC;</li>
- *     <li>DRMO: DRMO_SERVICE_ID;</li>
- *     <li>SXM: SXM_SERVICE_ID;</li>
+ *     <li>AM, FM: {@link #IDENTIFIER_TYPE_RDS_PI} if the station broadcasts RDS,
+ *     {@link #IDENTIFIER_TYPE_AMFM_FREQUENCY} otherwise;</li>
+ *     <li>AM_HD, FM_HD: {@link #IDENTIFIER_TYPE_HD_STATION_ID_EXT};</li>
+ *     <li>DAB: {@link #IDENTIFIER_TYPE_DAB_SID_EXT} or
+ *     {@link #IDENTIFIER_TYPE_DAB_DMB_SID_EXT};</li>
+ *     <li>DRMO: {@link #IDENTIFIER_TYPE_DRMO_SERVICE_ID};</li>
  *     <li>VENDOR: VENDOR_PRIMARY.</li>
  * </ui>
  * @hide
@@ -597,9 +595,9 @@
      * negatives. In particular, it may be way off for certain regions.
      * The main purpose is to avoid passing improper units, ie. MHz instead of kHz.
      *
-     * @param isAm true, if AM, false if FM.
+     * @param isAm {@code true}, if AM, {@code false} if FM.
      * @param frequencyKhz the frequency in kHz.
-     * @return true, if the frequency is roughly valid.
+     * @return {@code true}, if the frequency is roughly valid.
      */
     private static boolean isValidAmFmFrequency(boolean isAm, int frequencyKhz) {
         if (isAm) {
@@ -785,8 +783,8 @@
          * ProgramLists for category entries.
          *
          * @see ProgramList.Filter#areCategoriesIncluded
-         * @return False if this identifier's type is not tunable (e.g. DAB ensemble or
-         *         vendor-specified type). True otherwise.
+         * @return {@link false} if this identifier's type is not tunable (e.g. DAB ensemble or
+         *         vendor-specified type). {@link true} otherwise.
          */
         public boolean isCategoryType() {
             return (mType >= IDENTIFIER_TYPE_VENDOR_START && mType <= IDENTIFIER_TYPE_VENDOR_END)
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 5f3c15d..4c9e73c 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -3202,7 +3202,8 @@
      */
     @FlaggedApi(Flags.FLAG_ADAPTIVE_HANDWRITING_BOUNDS)
     public final void setStylusHandwritingRegion(@NonNull Region handwritingRegion) {
-        if (handwritingRegion.equals(mLastHandwritingRegion)) {
+        final Region immutableHandwritingRegion = new Region(handwritingRegion);
+        if (immutableHandwritingRegion.equals(mLastHandwritingRegion)) {
             Log.v(TAG, "Failed to set setStylusHandwritingRegion():"
                     + " same region set twice.");
             return;
@@ -3210,10 +3211,10 @@
 
         if (DEBUG) {
             Log.d(TAG, "Setting new handwriting region for stylus handwriting "
-                    + handwritingRegion + " from last " + mLastHandwritingRegion);
+                    + immutableHandwritingRegion + " from last " + mLastHandwritingRegion);
         }
-        mPrivOps.setHandwritingTouchableRegion(handwritingRegion);
-        mLastHandwritingRegion = handwritingRegion;
+        mPrivOps.setHandwritingTouchableRegion(immutableHandwritingRegion);
+        mLastHandwritingRegion = immutableHandwritingRegion;
     }
 
     /**
diff --git a/core/java/android/net/flags.aconfig b/core/java/android/net/flags.aconfig
index 95b5f69..6799db3 100644
--- a/core/java/android/net/flags.aconfig
+++ b/core/java/android/net/flags.aconfig
@@ -29,11 +29,3 @@
   }
   is_exported: true
 }
-
-flag {
-  name: "x509_extensions_certificate_transparency"
-  is_exported: true
-  namespace: "network_security"
-  description: "Flag to use checkServerTrusted to verify SCTs in OCSP and TLS Data"
-  bug: "319829948"
-}
diff --git a/core/java/android/net/http/X509TrustManagerExtensions.java b/core/java/android/net/http/X509TrustManagerExtensions.java
index b44f75a..3425b77 100644
--- a/core/java/android/net/http/X509TrustManagerExtensions.java
+++ b/core/java/android/net/http/X509TrustManagerExtensions.java
@@ -22,7 +22,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
-import android.net.platform.flags.Flags;
+import android.security.Flags;
 import android.security.net.config.UserCertificateSource;
 
 import com.android.org.conscrypt.TrustManagerImpl;
@@ -152,7 +152,7 @@
      * @throws IllegalArgumentException if the TrustManager is not compatible.
      * @return the properly ordered chain used for verification as a list of X509Certificates.
      */
-    @FlaggedApi(Flags.FLAG_X509_EXTENSIONS_CERTIFICATE_TRANSPARENCY)
+    @FlaggedApi(Flags.FLAG_CERTIFICATE_TRANSPARENCY_CONFIGURATION)
     @NonNull
     public List<X509Certificate> checkServerTrusted(
             @SuppressLint("ArrayReturn") @NonNull X509Certificate[] chain,
diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
index 11b80ce..230fa3f 100644
--- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java
+++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
@@ -1272,7 +1272,7 @@
         return true;
     }
 
-    private Message legacyPeekOrPop(boolean peek) {
+    private Message legacyPeekOrPoll(boolean peek) {
         synchronized (this) {
             // Try to retrieve the next message.  Return if found.
             final long now = SystemClock.uptimeMillis();
@@ -1331,7 +1331,7 @@
         if (mUseConcurrent) {
             ret = nextMessage(true);
         } else {
-            ret = legacyPeekOrPop(true);
+            ret = legacyPeekOrPoll(true);
         }
         return ret != null ? ret.when : null;
     }
@@ -1344,15 +1344,81 @@
      */
     @SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
     @Nullable
-    Message popForTest() {
+    Message pollForTest() {
         throwIfNotTest();
         if (mUseConcurrent) {
             return nextMessage(false);
         } else {
-            return legacyPeekOrPop(false);
+            return legacyPeekOrPoll(false);
         }
     }
 
+    /**
+     * @return true if we are blocked on a sync barrier
+     *
+     * Calls to this method must not be allowed to race with `next`.
+     * Specifically, the Looper thread must be paused before calling this method,
+     * and may not be resumed until after returning from this method.
+     */
+    boolean isBlockedOnSyncBarrier() {
+        throwIfNotTest();
+        if (mUseConcurrent) {
+            // Call nextMessage to get the stack drained into our priority queues
+            nextMessage(true);
+
+            Iterator<MessageNode> queueIter = mPriorityQueue.iterator();
+            MessageNode queueNode = iterateNext(queueIter);
+
+            if (queueNode != null && queueNode.isBarrier()) {
+                long now = SystemClock.uptimeMillis();
+
+                /* Look for a deliverable async node. If one exists we are not blocked. */
+                Iterator<MessageNode> asyncQueueIter = mAsyncPriorityQueue.iterator();
+                MessageNode asyncNode = iterateNext(asyncQueueIter);
+                if (asyncNode != null && now >= asyncNode.getWhen()) {
+                    return false;
+                }
+                /*
+                 * Look for a deliverable sync node. In this case, if one exists we are blocked
+                 * since the barrier prevents delivery of the Message.
+                 */
+                while (queueNode != null && queueNode.isBarrier()) {
+                    queueNode = iterateNext(queueIter);
+                }
+                if (queueNode != null && now >= queueNode.getWhen()) {
+                    return true;
+                }
+            }
+        } else {
+            Message msg = mMessages;
+            if (msg != null && msg.target == null) {
+                Message iter = msg;
+                /* Look for a deliverable async node */
+                do {
+                    iter = iter.next;
+                } while (iter != null && !iter.isAsynchronous());
+
+                long now = SystemClock.uptimeMillis();
+                if (iter != null && now >= iter.when) {
+                    return false;
+                }
+                /*
+                 * Look for a deliverable sync node. In this case, if one exists we are blocked
+                 * since the barrier prevents delivery of the Message.
+                 */
+                iter = msg;
+                do {
+                    iter = iter.next;
+                } while (iter != null && (iter.target == null || iter.isAsynchronous()));
+
+                if (iter != null && now >= iter.when) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     private static final class MatchHandlerWhatAndObject extends MessageCompare {
         @Override
         public boolean compareMessage(MessageNode n, Handler h, int what, Object object, Runnable r,
diff --git a/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
index 47778ed..d7d8e41 100644
--- a/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
+++ b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
@@ -19,6 +19,7 @@
 import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.app.ActivityThread;
 import android.app.Instrumentation;
@@ -784,7 +785,7 @@
             mMessageDirectlyQueued = false;
             nativePollOnce(ptr, mNextPollTimeoutMillis);
 
-            Message msg = nextMessage();
+            Message msg = nextMessage(false);
             if (msg != null) {
                 msg.markInUse();
                 return msg;
@@ -1087,7 +1088,6 @@
      *
      * Caller must ensure that this doesn't race 'next' from the Looper thread.
      */
-    @SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
     Long peekWhenForTest() {
         throwIfNotTest();
         Message ret = nextMessage(true);
@@ -1100,13 +1100,51 @@
      *
      * Caller must ensure that this doesn't race 'next' from the Looper thread.
      */
-    @SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
     @Nullable
-    Message popForTest() {
+    Message pollForTest() {
         throwIfNotTest();
         return nextMessage(false);
     }
 
+    /**
+     * @return true if we are blocked on a sync barrier
+     *
+     * Calls to this method must not be allowed to race with `next`.
+     * Specifically, the Looper thread must be paused before calling this method,
+     * and may not be resumed until after returning from this method.
+     */
+    boolean isBlockedOnSyncBarrier() {
+        throwIfNotTest();
+
+        // Call nextMessage to get the stack drained into our priority queues
+        nextMessage(true);
+
+        Iterator<MessageNode> queueIter = mPriorityQueue.iterator();
+        MessageNode queueNode = iterateNext(queueIter);
+
+        if (queueNode != null && queueNode.isBarrier()) {
+            long now = SystemClock.uptimeMillis();
+
+            /* Look for a deliverable async node. If one exists we are not blocked. */
+            Iterator<MessageNode> asyncQueueIter = mAsyncPriorityQueue.iterator();
+            MessageNode asyncNode = iterateNext(asyncQueueIter);
+            if (asyncNode != null && now >= asyncNode.getWhen()) {
+                return false;
+            }
+            /*
+             * Look for a deliverable sync node. In this case, if one exists we are blocked
+             * since the barrier prevents delivery of the Message.
+             */
+            while (queueNode != null && queueNode.isBarrier()) {
+                queueNode = iterateNext(queueIter);
+            }
+            if (queueNode != null && now >= queueNode.getWhen()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private StateNode getStateNode(StackNode node) {
         if (node.isMessageNode()) {
             return ((MessageNode) node).mBottomOfStack;
@@ -1161,7 +1199,7 @@
         MessageNode p = (MessageNode) top;
 
         while (true) {
-            if (compare.compareMessage(p.mMessage, h, what, object, r, when)) {
+            if (compare.compareMessage(p, h, what, object, r, when)) {
                 found = true;
                 if (DEBUG) {
                     Log.w(TAG, "stackHasMessages node matches");
@@ -1206,7 +1244,7 @@
         while (iterator.hasNext()) {
             MessageNode msg = iterator.next();
 
-            if (compare.compareMessage(msg.mMessage, h, what, object, r, when)) {
+            if (compare.compareMessage(msg, h, what, object, r, when)) {
                 if (removeMatches) {
                     found = true;
                     if (queue.remove(msg)) {
diff --git a/core/java/android/os/EventLogTags.logtags b/core/java/android/os/EventLogTags.logtags
index b143a74..f57aad0 100644
--- a/core/java/android/os/EventLogTags.logtags
+++ b/core/java/android/os/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
 
 option java_package android.os
 
diff --git a/core/java/android/os/IHintManager.aidl b/core/java/android/os/IHintManager.aidl
index 4a14a8d..56a089a 100644
--- a/core/java/android/os/IHintManager.aidl
+++ b/core/java/android/os/IHintManager.aidl
@@ -21,11 +21,13 @@
 import android.os.GpuHeadroomParamsInternal;
 import android.os.IHintSession;
 import android.os.SessionCreationConfig;
-import android.hardware.power.CpuHeadroomResult;
+
 import android.hardware.power.ChannelConfig;
+import android.hardware.power.CpuHeadroomResult;
 import android.hardware.power.GpuHeadroomResult;
 import android.hardware.power.SessionConfig;
 import android.hardware.power.SessionTag;
+import android.hardware.power.SupportInfo;
 
 /** {@hide} */
 interface IHintManager {
@@ -40,11 +42,6 @@
     IHintSession createHintSessionWithConfig(in IBinder token, in SessionTag tag,
             in SessionCreationConfig creationConfig, out SessionConfig config);
 
-    /**
-     * Get preferred rate limit in nanoseconds.
-     */
-    long getHintSessionPreferredRate();
-
     void setHintSessionThreads(in IHintSession hintSession, in int[] tids);
     int[] getHintSessionThreadIds(in IHintSession hintSession);
 
@@ -61,13 +58,28 @@
     long getGpuHeadroomMinIntervalMillis();
 
     /**
-     * Get Maximum number of graphics pipeline threads allowed per-app.
-     */
-    int getMaxGraphicsPipelineThreadsCount();
-
-    /**
      * Used by the JNI to pass an interface to the SessionManager;
      * for internal use only.
      */
     oneway void passSessionManagerBinder(in IBinder sessionManager);
+
+    parcelable HintManagerClientData {
+        int powerHalVersion;
+        int maxGraphicsPipelineThreads;
+        long preferredRateNanos;
+        SupportInfo supportInfo;
+    }
+
+    interface IHintManagerClient {
+        /**
+        * Returns FMQ channel information for the caller, which it associates to the callback binder lifespan.
+        */
+        oneway void receiveChannelConfig(in ChannelConfig config);
+    }
+
+    /**
+     * Set up an ADPF client, receiving a remote client binder interface and
+     * passing back a bundle of support and configuration information.
+     */
+    HintManagerClientData registerClient(in IHintManagerClient client);
 }
diff --git a/core/java/android/os/LegacyMessageQueue/MessageQueue.java b/core/java/android/os/LegacyMessageQueue/MessageQueue.java
index f49acd1..c0333e9 100644
--- a/core/java/android/os/LegacyMessageQueue/MessageQueue.java
+++ b/core/java/android/os/LegacyMessageQueue/MessageQueue.java
@@ -740,7 +740,7 @@
         return true;
     }
 
-    private Message legacyPeekOrPop(boolean peek) {
+    private Message legacyPeekOrPoll(boolean peek) {
         synchronized (this) {
             // Try to retrieve the next message.  Return if found.
             final long now = SystemClock.uptimeMillis();
@@ -795,7 +795,7 @@
     @SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
     Long peekWhenForTest() {
         throwIfNotTest();
-        Message ret = legacyPeekOrPop(true);
+        Message ret = legacyPeekOrPoll(true);
         return ret != null ? ret.when : null;
     }
 
@@ -807,9 +807,47 @@
      */
     @SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
     @Nullable
-    Message popForTest() {
+    Message pollForTest() {
         throwIfNotTest();
-        return legacyPeekOrPop(false);
+        return legacyPeekOrPoll(false);
+    }
+
+    /**
+     * @return true if we are blocked on a sync barrier
+     *
+     * Calls to this method must not be allowed to race with `next`.
+     * Specifically, the Looper thread must be paused before calling this method,
+     * and may not be resumed until after returning from this method.
+     */
+    boolean isBlockedOnSyncBarrier() {
+        throwIfNotTest();
+        Message msg = mMessages;
+        if (msg != null && msg.target == null) {
+            Message iter = msg;
+            /* Look for a deliverable async node */
+            do {
+                iter = iter.next;
+            } while (iter != null && !iter.isAsynchronous());
+
+            long now = SystemClock.uptimeMillis();
+            if (iter != null && now >= iter.when) {
+                return false;
+            }
+            /*
+                * Look for a deliverable sync node. In this case, if one exists we are blocked
+                * since the barrier prevents delivery of the Message.
+                */
+            iter = msg;
+            do {
+                iter = iter.next;
+            } while (iter != null && (iter.target == null || iter.isAsynchronous()));
+
+            if (iter != null && now >= iter.when) {
+                return true;
+            }
+            return false;
+        }
+        return false;
     }
 
     boolean hasMessages(Handler h, int what, Object object) {
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index ddf2b61..0125905 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -332,16 +332,55 @@
         return -1;
     }
 
+    private static int getThreadGroup() {
+        int threadGroup = Process.THREAD_GROUP_DEFAULT;
+
+        if (!Process.isIsolated()) {
+            threadGroup = Process.getProcessGroup(Process.myTid());
+        }
+        return threadGroup;
+    }
+
+    private static String threadGroupToString(int threadGroup) {
+        switch (threadGroup) {
+            case Process.THREAD_GROUP_BACKGROUND:
+                return "BACKGROUND";
+            case Process.THREAD_GROUP_FOREGROUND:
+                return "FOREGROUND";
+            case Process.THREAD_GROUP_SYSTEM:
+                return "SYSTEM";
+            case Process.THREAD_GROUP_AUDIO_APP:
+                return "AUDIO_APP";
+            case Process.THREAD_GROUP_AUDIO_SYS:
+                return "AUDIO_SYS";
+            case Process.THREAD_GROUP_TOP_APP:
+                return "TOP_APP";
+            case Process.THREAD_GROUP_RT_APP:
+                return "RT_APP";
+            case Process.THREAD_GROUP_RESTRICTED:
+                return "RESTRICTED";
+            default:
+                return "UNKNOWN";
+        }
+    }
+
     private static boolean showSlowLog(long threshold, long measureStart, long measureEnd,
             String what, Message msg) {
         final long actualTime = measureEnd - measureStart;
         if (actualTime < threshold) {
             return false;
         }
+
+        String name = Process.myProcessName();
+        String threadGroup = threadGroupToString(getThreadGroup());
+        boolean isMain = myLooper() == getMainLooper();
+
         // For slow delivery, the current message isn't really important, but log it anyway.
         Slog.w(TAG, "Slow " + what + " took " + actualTime + "ms "
-                + Thread.currentThread().getName() + " h="
-                + msg.target.getClass().getName() + " c=" + msg.callback + " m=" + msg.what);
+                + Thread.currentThread().getName() + " app=" + name
+                + " main=" + isMain + " group=" + threadGroup
+                + " h=" + msg.target.getClass().getName() + " c=" + msg.callback
+                + " m=" + msg.what);
         return true;
     }
 
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 8d35338..f3bb514 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -115,13 +115,20 @@
 # Performance
 per-file IpcDataCache.java = file:/PERFORMANCE_OWNERS
 
+# Processes, threads, and scheduling
+per-file Process.java = file:/PERFORMANCE_OWNERS
+
 # Memory
 per-file OomKillRecord.java = file:/MEMORY_OWNERS
 
 # MessageQueue and related classes
 per-file MessageQueue.java = mfasheh@google.com, shayba@google.com
 per-file Message.java = mfasheh@google.com, shayba@google.com
+per-file Looper.java = mfasheh@google.com, shayba@google.com
 per-file TestLooperManager.java = mfasheh@google.com, shayba@google.com
+per-file Handler.java = mfasheh@google.com, shayba@google.com
+per-file HandlerThread.java = mfasheh@google.com, shayba@google.com
+per-file HandlerExecutor.java = mfasheh@google.com, shayba@google.com
 
 # Stats
 per-file IStatsBootstrapAtomService.aidl = file:/services/core/java/com/android/server/stats/OWNERS
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index d7e7ff2..cf473ec 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -50,7 +50,6 @@
 
 import dalvik.annotation.optimization.CriticalNative;
 import dalvik.annotation.optimization.FastNative;
-import dalvik.annotation.optimization.NeverInline;
 
 import libcore.util.SneakyThrow;
 
@@ -588,17 +587,6 @@
         return parcel;
     }
 
-    @NeverInline
-    private void errorUsedWhileRecycling() {
-        Log.wtf(TAG, "Parcel used while recycled. "
-                + Log.getStackTraceString(new Throwable())
-                + " Original recycle call (if DEBUG_RECYCLE): ", mStack);
-    }
-
-    private void assertNotRecycled() {
-        if (mRecycled) errorUsedWhileRecycling();
-    }
-
     /**
      * Put a Parcel object back into the pool.  You must not touch
      * the object after this call.
@@ -647,7 +635,6 @@
      * @hide
      */
     public void setReadWriteHelper(@Nullable ReadWriteHelper helper) {
-        assertNotRecycled();
         mReadWriteHelper = helper != null ? helper : ReadWriteHelper.DEFAULT;
     }
 
@@ -657,7 +644,6 @@
      * @hide
      */
     public boolean hasReadWriteHelper() {
-        assertNotRecycled();
         return (mReadWriteHelper != null) && (mReadWriteHelper != ReadWriteHelper.DEFAULT);
     }
 
@@ -684,7 +670,6 @@
      * @hide
      */
     public final void markSensitive() {
-        assertNotRecycled();
         nativeMarkSensitive(mNativePtr);
     }
 
@@ -701,7 +686,6 @@
      * @hide
      */
     public final boolean isForRpc() {
-        assertNotRecycled();
         return nativeIsForRpc(mNativePtr);
     }
 
@@ -709,25 +693,21 @@
     @ParcelFlags
     @TestApi
     public int getFlags() {
-        assertNotRecycled();
         return mFlags;
     }
 
     /** @hide */
     public void setFlags(@ParcelFlags int flags) {
-        assertNotRecycled();
         mFlags = flags;
     }
 
     /** @hide */
     public void addFlags(@ParcelFlags int flags) {
-        assertNotRecycled();
         mFlags |= flags;
     }
 
     /** @hide */
     private boolean hasFlags(@ParcelFlags int flags) {
-        assertNotRecycled();
         return (mFlags & flags) == flags;
     }
 
@@ -740,7 +720,6 @@
     // We don't really need to protect it; even if 3p / non-system apps, nothing would happen.
     // This would only work when used on a reply parcel by a binder object that's allowed-blocking.
     public void setPropagateAllowBlocking() {
-        assertNotRecycled();
         addFlags(FLAG_PROPAGATE_ALLOW_BLOCKING);
     }
 
@@ -748,7 +727,6 @@
      * Returns the total amount of data contained in the parcel.
      */
     public int dataSize() {
-        assertNotRecycled();
         return nativeDataSize(mNativePtr);
     }
 
@@ -757,7 +735,6 @@
      * parcel.  That is, {@link #dataSize}-{@link #dataPosition}.
      */
     public final int dataAvail() {
-        assertNotRecycled();
         return nativeDataAvail(mNativePtr);
     }
 
@@ -766,7 +743,6 @@
      * more than {@link #dataSize}.
      */
     public final int dataPosition() {
-        assertNotRecycled();
         return nativeDataPosition(mNativePtr);
     }
 
@@ -777,7 +753,6 @@
      * data buffer.
      */
     public final int dataCapacity() {
-        assertNotRecycled();
         return nativeDataCapacity(mNativePtr);
     }
 
@@ -789,7 +764,6 @@
      * @param size The new number of bytes in the Parcel.
      */
     public final void setDataSize(int size) {
-        assertNotRecycled();
         nativeSetDataSize(mNativePtr, size);
     }
 
@@ -799,7 +773,6 @@
      * {@link #dataSize}.
      */
     public final void setDataPosition(int pos) {
-        assertNotRecycled();
         nativeSetDataPosition(mNativePtr, pos);
     }
 
@@ -811,13 +784,11 @@
      * with this method.
      */
     public final void setDataCapacity(int size) {
-        assertNotRecycled();
         nativeSetDataCapacity(mNativePtr, size);
     }
 
     /** @hide */
     public final boolean pushAllowFds(boolean allowFds) {
-        assertNotRecycled();
         return nativePushAllowFds(mNativePtr, allowFds);
     }
 
@@ -838,7 +809,6 @@
      * in different versions of the platform.
      */
     public final byte[] marshall() {
-        assertNotRecycled();
         return nativeMarshall(mNativePtr);
     }
 
@@ -846,18 +816,15 @@
      * Fills the raw bytes of this Parcel with the supplied data.
      */
     public final void unmarshall(@NonNull byte[] data, int offset, int length) {
-        assertNotRecycled();
         nativeUnmarshall(mNativePtr, data, offset, length);
     }
 
     public final void appendFrom(Parcel parcel, int offset, int length) {
-        assertNotRecycled();
         nativeAppendFrom(mNativePtr, parcel.mNativePtr, offset, length);
     }
 
     /** @hide */
     public int compareData(Parcel other) {
-        assertNotRecycled();
         return nativeCompareData(mNativePtr, other.mNativePtr);
     }
 
@@ -868,7 +835,6 @@
 
     /** @hide */
     public final void setClassCookie(Class clz, Object cookie) {
-        assertNotRecycled();
         if (mClassCookies == null) {
             mClassCookies = new ArrayMap<>();
         }
@@ -878,13 +844,11 @@
     /** @hide */
     @Nullable
     public final Object getClassCookie(Class clz) {
-        assertNotRecycled();
         return mClassCookies != null ? mClassCookies.get(clz) : null;
     }
 
     /** @hide */
     public void removeClassCookie(Class clz, Object expectedCookie) {
-        assertNotRecycled();
         if (mClassCookies != null) {
             Object removedCookie = mClassCookies.remove(clz);
             if (removedCookie != expectedCookie) {
@@ -902,25 +866,21 @@
      * @hide
      */
     public boolean hasClassCookie(Class clz) {
-        assertNotRecycled();
         return mClassCookies != null && mClassCookies.containsKey(clz);
     }
 
     /** @hide */
     public final void adoptClassCookies(Parcel from) {
-        assertNotRecycled();
         mClassCookies = from.mClassCookies;
     }
 
     /** @hide */
     public Map<Class, Object> copyClassCookies() {
-        assertNotRecycled();
         return new ArrayMap<>(mClassCookies);
     }
 
     /** @hide */
     public void putClassCookies(Map<Class, Object> cookies) {
-        assertNotRecycled();
         if (cookies == null) {
             return;
         }
@@ -940,7 +900,6 @@
      * if the return value changes.
      */
     public boolean hasFileDescriptors() {
-        assertNotRecycled();
         return nativeHasFileDescriptors(mNativePtr);
     }
 
@@ -962,7 +921,6 @@
      * @throws IllegalArgumentException if the parameters are out of the permitted ranges.
      */
     public boolean hasFileDescriptors(int offset, int length) {
-        assertNotRecycled();
         return nativeHasFileDescriptorsInRange(mNativePtr, offset, length);
     }
 
@@ -1060,7 +1018,6 @@
      * @hide
      */
     public boolean hasBinders() {
-        assertNotRecycled();
         return nativeHasBinders(mNativePtr);
     }
 
@@ -1084,7 +1041,6 @@
      * @hide
      */
     public boolean hasBinders(int offset, int length) {
-        assertNotRecycled();
         return nativeHasBindersInRange(mNativePtr, offset, length);
     }
 
@@ -1095,7 +1051,6 @@
      * at the beginning of transactions as a header.
      */
     public final void writeInterfaceToken(@NonNull String interfaceName) {
-        assertNotRecycled();
         nativeWriteInterfaceToken(mNativePtr, interfaceName);
     }
 
@@ -1106,7 +1061,6 @@
      * should propagate to the caller.
      */
     public final void enforceInterface(@NonNull String interfaceName) {
-        assertNotRecycled();
         nativeEnforceInterface(mNativePtr, interfaceName);
     }
 
@@ -1117,7 +1071,6 @@
      * When used over binder, this exception should propagate to the caller.
      */
     public void enforceNoDataAvail() {
-        assertNotRecycled();
         final int n = dataAvail();
         if (n > 0) {
             throw new BadParcelableException("Parcel data not fully consumed, unread size: " + n);
@@ -1134,7 +1087,6 @@
      * @hide
      */
     public boolean replaceCallingWorkSourceUid(int workSourceUid) {
-        assertNotRecycled();
         return nativeReplaceCallingWorkSourceUid(mNativePtr, workSourceUid);
     }
 
@@ -1151,7 +1103,6 @@
      * @hide
      */
     public int readCallingWorkSourceUid() {
-        assertNotRecycled();
         return nativeReadCallingWorkSourceUid(mNativePtr);
     }
 
@@ -1161,7 +1112,6 @@
      * @param b Bytes to place into the parcel.
      */
     public final void writeByteArray(@Nullable byte[] b) {
-        assertNotRecycled();
         writeByteArray(b, 0, (b != null) ? b.length : 0);
     }
 
@@ -1173,7 +1123,6 @@
      * @param len Number of bytes to write.
      */
     public final void writeByteArray(@Nullable byte[] b, int offset, int len) {
-        assertNotRecycled();
         if (b == null) {
             writeInt(-1);
             return;
@@ -1195,7 +1144,6 @@
      * @see #readBlob()
      */
     public final void writeBlob(@Nullable byte[] b) {
-        assertNotRecycled();
         writeBlob(b, 0, (b != null) ? b.length : 0);
     }
 
@@ -1214,7 +1162,6 @@
      * @see #readBlob()
      */
     public final void writeBlob(@Nullable byte[] b, int offset, int len) {
-        assertNotRecycled();
         if (b == null) {
             writeInt(-1);
             return;
@@ -1233,7 +1180,6 @@
      * growing dataCapacity() if needed.
      */
     public final void writeInt(int val) {
-        assertNotRecycled();
         int err = nativeWriteInt(mNativePtr, val);
         if (err != OK) {
             nativeSignalExceptionForError(err);
@@ -1245,7 +1191,6 @@
      * growing dataCapacity() if needed.
      */
     public final void writeLong(long val) {
-        assertNotRecycled();
         int err = nativeWriteLong(mNativePtr, val);
         if (err != OK) {
             nativeSignalExceptionForError(err);
@@ -1257,7 +1202,6 @@
      * dataPosition(), growing dataCapacity() if needed.
      */
     public final void writeFloat(float val) {
-        assertNotRecycled();
         int err = nativeWriteFloat(mNativePtr, val);
         if (err != OK) {
             nativeSignalExceptionForError(err);
@@ -1269,7 +1213,6 @@
      * current dataPosition(), growing dataCapacity() if needed.
      */
     public final void writeDouble(double val) {
-        assertNotRecycled();
         int err = nativeWriteDouble(mNativePtr, val);
         if (err != OK) {
             nativeSignalExceptionForError(err);
@@ -1281,19 +1224,16 @@
      * growing dataCapacity() if needed.
      */
     public final void writeString(@Nullable String val) {
-        assertNotRecycled();
         writeString16(val);
     }
 
     /** {@hide} */
     public final void writeString8(@Nullable String val) {
-        assertNotRecycled();
         mReadWriteHelper.writeString8(this, val);
     }
 
     /** {@hide} */
     public final void writeString16(@Nullable String val) {
-        assertNotRecycled();
         mReadWriteHelper.writeString16(this, val);
     }
 
@@ -1305,19 +1245,16 @@
      * @hide
      */
     public void writeStringNoHelper(@Nullable String val) {
-        assertNotRecycled();
         writeString16NoHelper(val);
     }
 
     /** {@hide} */
     public void writeString8NoHelper(@Nullable String val) {
-        assertNotRecycled();
         nativeWriteString8(mNativePtr, val);
     }
 
     /** {@hide} */
     public void writeString16NoHelper(@Nullable String val) {
-        assertNotRecycled();
         nativeWriteString16(mNativePtr, val);
     }
 
@@ -1329,7 +1266,6 @@
      * for true or false, respectively, but may change in the future.
      */
     public final void writeBoolean(boolean val) {
-        assertNotRecycled();
         writeInt(val ? 1 : 0);
     }
 
@@ -1341,7 +1277,6 @@
     @UnsupportedAppUsage
     @RavenwoodThrow(blockedBy = android.text.Spanned.class)
     public final void writeCharSequence(@Nullable CharSequence val) {
-        assertNotRecycled();
         TextUtils.writeToParcel(val, this, 0);
     }
 
@@ -1350,7 +1285,6 @@
      * growing dataCapacity() if needed.
      */
     public final void writeStrongBinder(IBinder val) {
-        assertNotRecycled();
         nativeWriteStrongBinder(mNativePtr, val);
     }
 
@@ -1359,7 +1293,6 @@
      * growing dataCapacity() if needed.
      */
     public final void writeStrongInterface(IInterface val) {
-        assertNotRecycled();
         writeStrongBinder(val == null ? null : val.asBinder());
     }
 
@@ -1374,7 +1307,6 @@
      * if {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} is set.</p>
      */
     public final void writeFileDescriptor(@NonNull FileDescriptor val) {
-        assertNotRecycled();
         nativeWriteFileDescriptor(mNativePtr, val);
     }
 
@@ -1383,7 +1315,6 @@
      * This will be the new name for writeFileDescriptor, for consistency.
      **/
     public final void writeRawFileDescriptor(@NonNull FileDescriptor val) {
-        assertNotRecycled();
         nativeWriteFileDescriptor(mNativePtr, val);
     }
 
@@ -1394,7 +1325,6 @@
      * @param value The array of objects to be written.
      */
     public final void writeRawFileDescriptorArray(@Nullable FileDescriptor[] value) {
-        assertNotRecycled();
         if (value != null) {
             int N = value.length;
             writeInt(N);
@@ -1414,7 +1344,6 @@
      * the future.
      */
     public final void writeByte(byte val) {
-        assertNotRecycled();
         writeInt(val);
     }
 
@@ -1430,7 +1359,6 @@
      * allows you to avoid mysterious type errors at the point of marshalling.
      */
     public final void writeMap(@Nullable Map val) {
-        assertNotRecycled();
         writeMapInternal((Map<String, Object>) val);
     }
 
@@ -1439,7 +1367,6 @@
      * growing dataCapacity() if needed.  The Map keys must be String objects.
      */
     /* package */ void writeMapInternal(@Nullable Map<String,Object> val) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -1465,7 +1392,6 @@
      * growing dataCapacity() if needed.  The Map keys must be String objects.
      */
     /* package */ void writeArrayMapInternal(@Nullable ArrayMap<String, Object> val) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -1495,7 +1421,6 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public void writeArrayMap(@Nullable ArrayMap<String, Object> val) {
-        assertNotRecycled();
         writeArrayMapInternal(val);
     }
 
@@ -1514,7 +1439,6 @@
      */
     public <T extends Parcelable> void writeTypedArrayMap(@Nullable ArrayMap<String, T> val,
             int parcelableFlags) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -1536,7 +1460,6 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public void writeArraySet(@Nullable ArraySet<? extends Object> val) {
-        assertNotRecycled();
         final int size = (val != null) ? val.size() : -1;
         writeInt(size);
         for (int i = 0; i < size; i++) {
@@ -1549,7 +1472,6 @@
      * growing dataCapacity() if needed.
      */
     public final void writeBundle(@Nullable Bundle val) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -1563,7 +1485,6 @@
      * growing dataCapacity() if needed.
      */
     public final void writePersistableBundle(@Nullable PersistableBundle val) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -1577,7 +1498,6 @@
      * growing dataCapacity() if needed.
      */
     public final void writeSize(@NonNull Size val) {
-        assertNotRecycled();
         writeInt(val.getWidth());
         writeInt(val.getHeight());
     }
@@ -1587,7 +1507,6 @@
      * growing dataCapacity() if needed.
      */
     public final void writeSizeF(@NonNull SizeF val) {
-        assertNotRecycled();
         writeFloat(val.getWidth());
         writeFloat(val.getHeight());
     }
@@ -1598,7 +1517,6 @@
      * {@link #writeValue} and must follow the specification there.
      */
     public final void writeList(@Nullable List val) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -1618,7 +1536,6 @@
      * {@link #writeValue} and must follow the specification there.
      */
     public final void writeArray(@Nullable Object[] val) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -1639,7 +1556,6 @@
      * specification there.
      */
     public final <T> void writeSparseArray(@Nullable SparseArray<T> val) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -1655,7 +1571,6 @@
     }
 
     public final void writeSparseBooleanArray(@Nullable SparseBooleanArray val) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -1674,7 +1589,6 @@
      * @hide
      */
     public final void writeSparseIntArray(@Nullable SparseIntArray val) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -1690,7 +1604,6 @@
     }
 
     public final void writeBooleanArray(@Nullable boolean[] val) {
-        assertNotRecycled();
         if (val != null) {
             int N = val.length;
             writeInt(N);
@@ -1725,7 +1638,6 @@
     }
 
     private void ensureWithinMemoryLimit(int typeSize, @NonNull int... dimensions) {
-        assertNotRecycled();
         // For Multidimensional arrays, Calculate total object
         // which will be allocated.
         int totalObjects = 1;
@@ -1743,7 +1655,6 @@
     }
 
     private void ensureWithinMemoryLimit(int typeSize, int length) {
-        assertNotRecycled();
         int estimatedAllocationSize = 0;
         try {
             estimatedAllocationSize = Math.multiplyExact(typeSize, length);
@@ -1767,7 +1678,6 @@
 
     @Nullable
     public final boolean[] createBooleanArray() {
-        assertNotRecycled();
         int N = readInt();
         ensureWithinMemoryLimit(SIZE_BOOLEAN, N);
         // >>2 as a fast divide-by-4 works in the create*Array() functions
@@ -1785,7 +1695,6 @@
     }
 
     public final void readBooleanArray(@NonNull boolean[] val) {
-        assertNotRecycled();
         int N = readInt();
         if (N == val.length) {
             for (int i=0; i<N; i++) {
@@ -1798,7 +1707,6 @@
 
     /** @hide */
     public void writeShortArray(@Nullable short[] val) {
-        assertNotRecycled();
         if (val != null) {
             int n = val.length;
             writeInt(n);
@@ -1813,7 +1721,6 @@
     /** @hide */
     @Nullable
     public short[] createShortArray() {
-        assertNotRecycled();
         int n = readInt();
         ensureWithinMemoryLimit(SIZE_SHORT, n);
         if (n >= 0 && n <= (dataAvail() >> 2)) {
@@ -1829,7 +1736,6 @@
 
     /** @hide */
     public void readShortArray(@NonNull short[] val) {
-        assertNotRecycled();
         int n = readInt();
         if (n == val.length) {
             for (int i = 0; i < n; i++) {
@@ -1841,7 +1747,6 @@
     }
 
     public final void writeCharArray(@Nullable char[] val) {
-        assertNotRecycled();
         if (val != null) {
             int N = val.length;
             writeInt(N);
@@ -1855,7 +1760,6 @@
 
     @Nullable
     public final char[] createCharArray() {
-        assertNotRecycled();
         int N = readInt();
         ensureWithinMemoryLimit(SIZE_CHAR, N);
         if (N >= 0 && N <= (dataAvail() >> 2)) {
@@ -1870,7 +1774,6 @@
     }
 
     public final void readCharArray(@NonNull char[] val) {
-        assertNotRecycled();
         int N = readInt();
         if (N == val.length) {
             for (int i=0; i<N; i++) {
@@ -1882,7 +1785,6 @@
     }
 
     public final void writeIntArray(@Nullable int[] val) {
-        assertNotRecycled();
         if (val != null) {
             int N = val.length;
             writeInt(N);
@@ -1896,7 +1798,6 @@
 
     @Nullable
     public final int[] createIntArray() {
-        assertNotRecycled();
         int N = readInt();
         ensureWithinMemoryLimit(SIZE_INT, N);
         if (N >= 0 && N <= (dataAvail() >> 2)) {
@@ -1911,7 +1812,6 @@
     }
 
     public final void readIntArray(@NonNull int[] val) {
-        assertNotRecycled();
         int N = readInt();
         if (N == val.length) {
             for (int i=0; i<N; i++) {
@@ -1923,7 +1823,6 @@
     }
 
     public final void writeLongArray(@Nullable long[] val) {
-        assertNotRecycled();
         if (val != null) {
             int N = val.length;
             writeInt(N);
@@ -1937,7 +1836,6 @@
 
     @Nullable
     public final long[] createLongArray() {
-        assertNotRecycled();
         int N = readInt();
         ensureWithinMemoryLimit(SIZE_LONG, N);
         // >>3 because stored longs are 64 bits
@@ -1953,7 +1851,6 @@
     }
 
     public final void readLongArray(@NonNull long[] val) {
-        assertNotRecycled();
         int N = readInt();
         if (N == val.length) {
             for (int i=0; i<N; i++) {
@@ -1965,7 +1862,6 @@
     }
 
     public final void writeFloatArray(@Nullable float[] val) {
-        assertNotRecycled();
         if (val != null) {
             int N = val.length;
             writeInt(N);
@@ -1979,7 +1875,6 @@
 
     @Nullable
     public final float[] createFloatArray() {
-        assertNotRecycled();
         int N = readInt();
         ensureWithinMemoryLimit(SIZE_FLOAT, N);
         // >>2 because stored floats are 4 bytes
@@ -1995,7 +1890,6 @@
     }
 
     public final void readFloatArray(@NonNull float[] val) {
-        assertNotRecycled();
         int N = readInt();
         if (N == val.length) {
             for (int i=0; i<N; i++) {
@@ -2007,7 +1901,6 @@
     }
 
     public final void writeDoubleArray(@Nullable double[] val) {
-        assertNotRecycled();
         if (val != null) {
             int N = val.length;
             writeInt(N);
@@ -2021,7 +1914,6 @@
 
     @Nullable
     public final double[] createDoubleArray() {
-        assertNotRecycled();
         int N = readInt();
         ensureWithinMemoryLimit(SIZE_DOUBLE, N);
         // >>3 because stored doubles are 8 bytes
@@ -2037,7 +1929,6 @@
     }
 
     public final void readDoubleArray(@NonNull double[] val) {
-        assertNotRecycled();
         int N = readInt();
         if (N == val.length) {
             for (int i=0; i<N; i++) {
@@ -2049,24 +1940,20 @@
     }
 
     public final void writeStringArray(@Nullable String[] val) {
-        assertNotRecycled();
         writeString16Array(val);
     }
 
     @Nullable
     public final String[] createStringArray() {
-        assertNotRecycled();
         return createString16Array();
     }
 
     public final void readStringArray(@NonNull String[] val) {
-        assertNotRecycled();
         readString16Array(val);
     }
 
     /** {@hide} */
     public final void writeString8Array(@Nullable String[] val) {
-        assertNotRecycled();
         if (val != null) {
             int N = val.length;
             writeInt(N);
@@ -2081,7 +1968,6 @@
     /** {@hide} */
     @Nullable
     public final String[] createString8Array() {
-        assertNotRecycled();
         int N = readInt();
         ensureWithinMemoryLimit(SIZE_COMPLEX_TYPE, N);
         if (N >= 0) {
@@ -2097,7 +1983,6 @@
 
     /** {@hide} */
     public final void readString8Array(@NonNull String[] val) {
-        assertNotRecycled();
         int N = readInt();
         if (N == val.length) {
             for (int i=0; i<N; i++) {
@@ -2110,7 +1995,6 @@
 
     /** {@hide} */
     public final void writeString16Array(@Nullable String[] val) {
-        assertNotRecycled();
         if (val != null) {
             int N = val.length;
             writeInt(N);
@@ -2125,7 +2009,6 @@
     /** {@hide} */
     @Nullable
     public final String[] createString16Array() {
-        assertNotRecycled();
         int N = readInt();
         ensureWithinMemoryLimit(SIZE_COMPLEX_TYPE, N);
         if (N >= 0) {
@@ -2141,7 +2024,6 @@
 
     /** {@hide} */
     public final void readString16Array(@NonNull String[] val) {
-        assertNotRecycled();
         int N = readInt();
         if (N == val.length) {
             for (int i=0; i<N; i++) {
@@ -2153,7 +2035,6 @@
     }
 
     public final void writeBinderArray(@Nullable IBinder[] val) {
-        assertNotRecycled();
         if (val != null) {
             int N = val.length;
             writeInt(N);
@@ -2178,7 +2059,6 @@
      */
     public final <T extends IInterface> void writeInterfaceArray(
             @SuppressLint("ArrayReturn") @Nullable T[] val) {
-        assertNotRecycled();
         if (val != null) {
             int N = val.length;
             writeInt(N);
@@ -2194,7 +2074,6 @@
      * @hide
      */
     public final void writeCharSequenceArray(@Nullable CharSequence[] val) {
-        assertNotRecycled();
         if (val != null) {
             int N = val.length;
             writeInt(N);
@@ -2210,7 +2089,6 @@
      * @hide
      */
     public final void writeCharSequenceList(@Nullable ArrayList<CharSequence> val) {
-        assertNotRecycled();
         if (val != null) {
             int N = val.size();
             writeInt(N);
@@ -2224,7 +2102,6 @@
 
     @Nullable
     public final IBinder[] createBinderArray() {
-        assertNotRecycled();
         int N = readInt();
         ensureWithinMemoryLimit(SIZE_COMPLEX_TYPE, N);
         if (N >= 0) {
@@ -2239,7 +2116,6 @@
     }
 
     public final void readBinderArray(@NonNull IBinder[] val) {
-        assertNotRecycled();
         int N = readInt();
         if (N == val.length) {
             for (int i=0; i<N; i++) {
@@ -2261,7 +2137,6 @@
     @Nullable
     public final <T extends IInterface> T[] createInterfaceArray(
             @NonNull IntFunction<T[]> newArray, @NonNull Function<IBinder, T> asInterface) {
-        assertNotRecycled();
         int N = readInt();
         ensureWithinMemoryLimit(SIZE_COMPLEX_TYPE, N);
         if (N >= 0) {
@@ -2286,7 +2161,6 @@
     public final <T extends IInterface> void readInterfaceArray(
             @SuppressLint("ArrayReturn") @NonNull T[] val,
             @NonNull Function<IBinder, T> asInterface) {
-        assertNotRecycled();
         int N = readInt();
         if (N == val.length) {
             for (int i=0; i<N; i++) {
@@ -2312,7 +2186,6 @@
      * @see Parcelable
      */
     public final <T extends Parcelable> void writeTypedList(@Nullable List<T> val) {
-        assertNotRecycled();
         writeTypedList(val, 0);
     }
 
@@ -2332,7 +2205,6 @@
      */
     public final <T extends Parcelable> void writeTypedSparseArray(@Nullable SparseArray<T> val,
             int parcelableFlags) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -2362,7 +2234,6 @@
      * @see Parcelable
      */
     public <T extends Parcelable> void writeTypedList(@Nullable List<T> val, int parcelableFlags) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -2388,7 +2259,6 @@
      * @see #readStringList
      */
     public final void writeStringList(@Nullable List<String> val) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -2414,7 +2284,6 @@
      * @see #readBinderList
      */
     public final void writeBinderList(@Nullable List<IBinder> val) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -2437,7 +2306,6 @@
      * @see #readInterfaceList
      */
     public final <T extends IInterface> void writeInterfaceList(@Nullable List<T> val) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -2459,7 +2327,6 @@
      * @see #readParcelableList(List, ClassLoader)
      */
     public final <T extends Parcelable> void writeParcelableList(@Nullable List<T> val, int flags) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -2494,7 +2361,6 @@
      */
     public final <T extends Parcelable> void writeTypedArray(@Nullable T[] val,
             int parcelableFlags) {
-        assertNotRecycled();
         if (val != null) {
             int N = val.length;
             writeInt(N);
@@ -2517,7 +2383,6 @@
      */
     public final <T extends Parcelable> void writeTypedObject(@Nullable T val,
             int parcelableFlags) {
-        assertNotRecycled();
         if (val != null) {
             writeInt(1);
             val.writeToParcel(this, parcelableFlags);
@@ -2555,7 +2420,6 @@
      */
     public <T> void writeFixedArray(@Nullable T val, int parcelableFlags,
             @NonNull int... dimensions) {
-        assertNotRecycled();
         if (val == null) {
             writeInt(-1);
             return;
@@ -2667,7 +2531,6 @@
      * should be used).</p>
      */
     public final void writeValue(@Nullable Object v) {
-        assertNotRecycled();
         if (v instanceof LazyValue) {
             LazyValue value = (LazyValue) v;
             value.writeToParcel(this);
@@ -2785,7 +2648,6 @@
      * @hide
      */
     public void writeValue(int type, @Nullable Object v) {
-        assertNotRecycled();
         switch (type) {
             case VAL_NULL:
                 break;
@@ -2899,7 +2761,6 @@
      * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
      */
     public final void writeParcelable(@Nullable Parcelable p, int parcelableFlags) {
-        assertNotRecycled();
         if (p == null) {
             writeString(null);
             return;
@@ -2915,7 +2776,6 @@
      * @see #readParcelableCreator
      */
     public final void writeParcelableCreator(@NonNull Parcelable p) {
-        assertNotRecycled();
         String name = p.getClass().getName();
         writeString(name);
     }
@@ -2954,7 +2814,6 @@
      */
     @TestApi
     public boolean allowSquashing() {
-        assertNotRecycled();
         boolean previous = mAllowSquashing;
         mAllowSquashing = true;
         return previous;
@@ -2966,7 +2825,6 @@
      */
     @TestApi
     public void restoreAllowSquashing(boolean previous) {
-        assertNotRecycled();
         mAllowSquashing = previous;
         if (!mAllowSquashing) {
             mWrittenSquashableParcelables = null;
@@ -3023,7 +2881,6 @@
      * @hide
      */
     public boolean maybeWriteSquashed(@NonNull Parcelable p) {
-        assertNotRecycled();
         if (!mAllowSquashing) {
             // Don't squash, and don't put it in the map either.
             writeInt(0);
@@ -3074,7 +2931,6 @@
     @SuppressWarnings("unchecked")
     @Nullable
     public <T extends Parcelable> T readSquashed(SquashReadHelper<T> reader) {
-        assertNotRecycled();
         final int offset = readInt();
         final int pos = dataPosition();
 
@@ -3108,7 +2964,6 @@
      * using the other approaches to writing data in to a Parcel.
      */
     public final void writeSerializable(@Nullable Serializable s) {
-        assertNotRecycled();
         if (s == null) {
             writeString(null);
             return;
@@ -3161,7 +3016,6 @@
      */
     @RavenwoodReplace(blockedBy = AppOpsManager.class)
     public final void writeException(@NonNull Exception e) {
-        assertNotRecycled();
         AppOpsManager.prefixParcelWithAppOpsIfNeeded(this);
 
         int code = getExceptionCode(e);
@@ -3242,7 +3096,6 @@
 
     /** @hide */
     public void writeStackTrace(@NonNull Throwable e) {
-        assertNotRecycled();
         final int sizePosition = dataPosition();
         writeInt(0); // Header size will be filled in later
         StackTraceElement[] stackTrace = e.getStackTrace();
@@ -3268,7 +3121,6 @@
      */
     @RavenwoodReplace(blockedBy = AppOpsManager.class)
     public final void writeNoException() {
-        assertNotRecycled();
         AppOpsManager.prefixParcelWithAppOpsIfNeeded(this);
 
         // Despite the name of this function ("write no exception"),
@@ -3312,7 +3164,6 @@
      * @see #writeNoException
      */
     public final void readException() {
-        assertNotRecycled();
         int code = readExceptionCode();
         if (code != 0) {
             String msg = readString();
@@ -3336,7 +3187,6 @@
     @UnsupportedAppUsage
     @TestApi
     public final int readExceptionCode() {
-        assertNotRecycled();
         int code = readInt();
         if (code == EX_HAS_NOTED_APPOPS_REPLY_HEADER) {
             AppOpsManager.readAndLogNotedAppops(this);
@@ -3370,7 +3220,6 @@
      * @param msg The exception message.
      */
     public final void readException(int code, String msg) {
-        assertNotRecycled();
         String remoteStackTrace = null;
         final int remoteStackPayloadSize = readInt();
         if (remoteStackPayloadSize > 0) {
@@ -3401,7 +3250,6 @@
 
     /** @hide */
     public Exception createExceptionOrNull(int code, String msg) {
-        assertNotRecycled();
         switch (code) {
             case EX_PARCELABLE:
                 if (readInt() > 0) {
@@ -3434,7 +3282,6 @@
      * Read an integer value from the parcel at the current dataPosition().
      */
     public final int readInt() {
-        assertNotRecycled();
         return nativeReadInt(mNativePtr);
     }
 
@@ -3442,7 +3289,6 @@
      * Read a long integer value from the parcel at the current dataPosition().
      */
     public final long readLong() {
-        assertNotRecycled();
         return nativeReadLong(mNativePtr);
     }
 
@@ -3451,7 +3297,6 @@
      * dataPosition().
      */
     public final float readFloat() {
-        assertNotRecycled();
         return nativeReadFloat(mNativePtr);
     }
 
@@ -3460,7 +3305,6 @@
      * current dataPosition().
      */
     public final double readDouble() {
-        assertNotRecycled();
         return nativeReadDouble(mNativePtr);
     }
 
@@ -3469,19 +3313,16 @@
      */
     @Nullable
     public final String readString() {
-        assertNotRecycled();
         return readString16();
     }
 
     /** {@hide} */
     public final @Nullable String readString8() {
-        assertNotRecycled();
         return mReadWriteHelper.readString8(this);
     }
 
     /** {@hide} */
     public final @Nullable String readString16() {
-        assertNotRecycled();
         return mReadWriteHelper.readString16(this);
     }
 
@@ -3493,19 +3334,16 @@
      * @hide
      */
     public @Nullable String readStringNoHelper() {
-        assertNotRecycled();
         return readString16NoHelper();
     }
 
     /** {@hide} */
     public @Nullable String readString8NoHelper() {
-        assertNotRecycled();
         return nativeReadString8(mNativePtr);
     }
 
     /** {@hide} */
     public @Nullable String readString16NoHelper() {
-        assertNotRecycled();
         return nativeReadString16(mNativePtr);
     }
 
@@ -3513,7 +3351,6 @@
      * Read a boolean value from the parcel at the current dataPosition().
      */
     public final boolean readBoolean() {
-        assertNotRecycled();
         return readInt() != 0;
     }
 
@@ -3524,7 +3361,6 @@
     @UnsupportedAppUsage
     @Nullable
     public final CharSequence readCharSequence() {
-        assertNotRecycled();
         return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(this);
     }
 
@@ -3532,7 +3368,6 @@
      * Read an object from the parcel at the current dataPosition().
      */
     public final IBinder readStrongBinder() {
-        assertNotRecycled();
         final IBinder result = nativeReadStrongBinder(mNativePtr);
 
         // If it's a reply from a method with @PropagateAllowBlocking, then inherit allow-blocking
@@ -3548,7 +3383,6 @@
      * Read a FileDescriptor from the parcel at the current dataPosition().
      */
     public final ParcelFileDescriptor readFileDescriptor() {
-        assertNotRecycled();
         FileDescriptor fd = nativeReadFileDescriptor(mNativePtr);
         return fd != null ? new ParcelFileDescriptor(fd) : null;
     }
@@ -3556,7 +3390,6 @@
     /** {@hide} */
     @UnsupportedAppUsage
     public final FileDescriptor readRawFileDescriptor() {
-        assertNotRecycled();
         return nativeReadFileDescriptor(mNativePtr);
     }
 
@@ -3567,7 +3400,6 @@
      **/
     @Nullable
     public final FileDescriptor[] createRawFileDescriptorArray() {
-        assertNotRecycled();
         int N = readInt();
         if (N < 0) {
             return null;
@@ -3587,7 +3419,6 @@
      * @return the FileDescriptor array, or null if the array is null.
      **/
     public final void readRawFileDescriptorArray(FileDescriptor[] val) {
-        assertNotRecycled();
         int N = readInt();
         if (N == val.length) {
             for (int i=0; i<N; i++) {
@@ -3602,7 +3433,6 @@
      * Read a byte value from the parcel at the current dataPosition().
      */
     public final byte readByte() {
-        assertNotRecycled();
         return (byte)(readInt() & 0xff);
     }
 
@@ -3617,7 +3447,6 @@
      */
     @Deprecated
     public final void readMap(@NonNull Map outVal, @Nullable ClassLoader loader) {
-        assertNotRecycled();
         readMapInternal(outVal, loader, /* clazzKey */ null, /* clazzValue */ null);
     }
 
@@ -3631,7 +3460,6 @@
     public <K, V> void readMap(@NonNull Map<? super K, ? super V> outVal,
             @Nullable ClassLoader loader, @NonNull Class<K> clazzKey,
             @NonNull Class<V> clazzValue) {
-        assertNotRecycled();
         Objects.requireNonNull(clazzKey);
         Objects.requireNonNull(clazzValue);
         readMapInternal(outVal, loader, clazzKey, clazzValue);
@@ -3650,7 +3478,6 @@
      */
     @Deprecated
     public final void readList(@NonNull List outVal, @Nullable ClassLoader loader) {
-        assertNotRecycled();
         int N = readInt();
         readListInternal(outVal, N, loader, /* clazz */ null);
     }
@@ -3672,7 +3499,6 @@
      */
     public <T> void readList(@NonNull List<? super T> outVal,
             @Nullable ClassLoader loader, @NonNull Class<T> clazz) {
-        assertNotRecycled();
         Objects.requireNonNull(clazz);
         int n = readInt();
         readListInternal(outVal, n, loader, clazz);
@@ -3692,7 +3518,6 @@
     @Deprecated
     @Nullable
     public HashMap readHashMap(@Nullable ClassLoader loader) {
-        assertNotRecycled();
         return readHashMapInternal(loader, /* clazzKey */ null, /* clazzValue */ null);
     }
 
@@ -3707,7 +3532,6 @@
     @Nullable
     public <K, V> HashMap<K, V> readHashMap(@Nullable ClassLoader loader,
             @NonNull Class<? extends K> clazzKey, @NonNull Class<? extends V> clazzValue) {
-        assertNotRecycled();
         Objects.requireNonNull(clazzKey);
         Objects.requireNonNull(clazzValue);
         return readHashMapInternal(loader, clazzKey, clazzValue);
@@ -3720,7 +3544,6 @@
      */
     @Nullable
     public final Bundle readBundle() {
-        assertNotRecycled();
         return readBundle(null);
     }
 
@@ -3732,7 +3555,6 @@
      */
     @Nullable
     public final Bundle readBundle(@Nullable ClassLoader loader) {
-        assertNotRecycled();
         int length = readInt();
         if (length < 0) {
             if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
@@ -3753,7 +3575,6 @@
      */
     @Nullable
     public final PersistableBundle readPersistableBundle() {
-        assertNotRecycled();
         return readPersistableBundle(null);
     }
 
@@ -3765,7 +3586,6 @@
      */
     @Nullable
     public final PersistableBundle readPersistableBundle(@Nullable ClassLoader loader) {
-        assertNotRecycled();
         int length = readInt();
         if (length < 0) {
             if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
@@ -3784,7 +3604,6 @@
      */
     @NonNull
     public final Size readSize() {
-        assertNotRecycled();
         final int width = readInt();
         final int height = readInt();
         return new Size(width, height);
@@ -3795,7 +3614,6 @@
      */
     @NonNull
     public final SizeF readSizeF() {
-        assertNotRecycled();
         final float width = readFloat();
         final float height = readFloat();
         return new SizeF(width, height);
@@ -3806,7 +3624,6 @@
      */
     @Nullable
     public final byte[] createByteArray() {
-        assertNotRecycled();
         return nativeCreateByteArray(mNativePtr);
     }
 
@@ -3815,7 +3632,6 @@
      * given byte array.
      */
     public final void readByteArray(@NonNull byte[] val) {
-        assertNotRecycled();
         boolean valid = nativeReadByteArray(mNativePtr, val, (val != null) ? val.length : 0);
         if (!valid) {
             throw new RuntimeException("bad array lengths");
@@ -3828,7 +3644,6 @@
      */
     @Nullable
     public final byte[] readBlob() {
-        assertNotRecycled();
         return nativeReadBlob(mNativePtr);
     }
 
@@ -3839,7 +3654,6 @@
     @UnsupportedAppUsage
     @Nullable
     public final String[] readStringArray() {
-        assertNotRecycled();
         return createString16Array();
     }
 
@@ -3849,7 +3663,6 @@
      */
     @Nullable
     public final CharSequence[] readCharSequenceArray() {
-        assertNotRecycled();
         CharSequence[] array = null;
 
         int length = readInt();
@@ -3872,7 +3685,6 @@
      */
     @Nullable
     public final ArrayList<CharSequence> readCharSequenceList() {
-        assertNotRecycled();
         ArrayList<CharSequence> array = null;
 
         int length = readInt();
@@ -3902,7 +3714,6 @@
     @Deprecated
     @Nullable
     public ArrayList readArrayList(@Nullable ClassLoader loader) {
-        assertNotRecycled();
         return readArrayListInternal(loader, /* clazz */ null);
     }
 
@@ -3925,7 +3736,6 @@
     @Nullable
     public <T> ArrayList<T> readArrayList(@Nullable ClassLoader loader,
             @NonNull Class<? extends T> clazz) {
-        assertNotRecycled();
         Objects.requireNonNull(clazz);
         return readArrayListInternal(loader, clazz);
     }
@@ -3945,7 +3755,6 @@
     @Deprecated
     @Nullable
     public Object[] readArray(@Nullable ClassLoader loader) {
-        assertNotRecycled();
         return readArrayInternal(loader, /* clazz */ null);
     }
 
@@ -3967,7 +3776,6 @@
     @SuppressLint({"ArrayReturn", "NullableCollection"})
     @Nullable
     public <T> T[] readArray(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
-        assertNotRecycled();
         Objects.requireNonNull(clazz);
         return readArrayInternal(loader, clazz);
     }
@@ -3987,7 +3795,6 @@
     @Deprecated
     @Nullable
     public <T> SparseArray<T> readSparseArray(@Nullable ClassLoader loader) {
-        assertNotRecycled();
         return readSparseArrayInternal(loader, /* clazz */ null);
     }
 
@@ -4009,7 +3816,6 @@
     @Nullable
     public <T> SparseArray<T> readSparseArray(@Nullable ClassLoader loader,
             @NonNull Class<? extends T> clazz) {
-        assertNotRecycled();
         Objects.requireNonNull(clazz);
         return readSparseArrayInternal(loader, clazz);
     }
@@ -4021,7 +3827,6 @@
      */
     @Nullable
     public final SparseBooleanArray readSparseBooleanArray() {
-        assertNotRecycled();
         int N = readInt();
         if (N < 0) {
             return null;
@@ -4038,7 +3843,6 @@
      */
     @Nullable
     public final SparseIntArray readSparseIntArray() {
-        assertNotRecycled();
         int N = readInt();
         if (N < 0) {
             return null;
@@ -4063,7 +3867,6 @@
      */
     @Nullable
     public final <T> ArrayList<T> createTypedArrayList(@NonNull Parcelable.Creator<T> c) {
-        assertNotRecycled();
         int N = readInt();
         if (N < 0) {
             return null;
@@ -4087,7 +3890,6 @@
      * @see #writeTypedList
      */
     public final <T> void readTypedList(@NonNull List<T> list, @NonNull Parcelable.Creator<T> c) {
-        assertNotRecycled();
         int M = list.size();
         int N = readInt();
         int i = 0;
@@ -4117,7 +3919,6 @@
      */
     public final @Nullable <T extends Parcelable> SparseArray<T> createTypedSparseArray(
             @NonNull Parcelable.Creator<T> creator) {
-        assertNotRecycled();
         final int count = readInt();
         if (count < 0) {
             return null;
@@ -4147,7 +3948,6 @@
      */
     public final @Nullable <T extends Parcelable> ArrayMap<String, T> createTypedArrayMap(
             @NonNull Parcelable.Creator<T> creator) {
-        assertNotRecycled();
         final int count = readInt();
         if (count < 0) {
             return null;
@@ -4175,7 +3975,6 @@
      */
     @Nullable
     public final ArrayList<String> createStringArrayList() {
-        assertNotRecycled();
         int N = readInt();
         if (N < 0) {
             return null;
@@ -4202,7 +4001,6 @@
      */
     @Nullable
     public final ArrayList<IBinder> createBinderArrayList() {
-        assertNotRecycled();
         int N = readInt();
         if (N < 0) {
             return null;
@@ -4230,7 +4028,6 @@
     @Nullable
     public final <T extends IInterface> ArrayList<T> createInterfaceArrayList(
             @NonNull Function<IBinder, T> asInterface) {
-        assertNotRecycled();
         int N = readInt();
         if (N < 0) {
             return null;
@@ -4251,7 +4048,6 @@
      * @see #writeStringList
      */
     public final void readStringList(@NonNull List<String> list) {
-        assertNotRecycled();
         int M = list.size();
         int N = readInt();
         int i = 0;
@@ -4273,7 +4069,6 @@
      * @see #writeBinderList
      */
     public final void readBinderList(@NonNull List<IBinder> list) {
-        assertNotRecycled();
         int M = list.size();
         int N = readInt();
         int i = 0;
@@ -4296,7 +4091,6 @@
      */
     public final <T extends IInterface> void readInterfaceList(@NonNull List<T> list,
             @NonNull Function<IBinder, T> asInterface) {
-        assertNotRecycled();
         int M = list.size();
         int N = readInt();
         int i = 0;
@@ -4328,7 +4122,6 @@
     @NonNull
     public final <T extends Parcelable> List<T> readParcelableList(@NonNull List<T> list,
             @Nullable ClassLoader cl) {
-        assertNotRecycled();
         return readParcelableListInternal(list, cl, /*clazz*/ null);
     }
 
@@ -4350,7 +4143,6 @@
     @NonNull
     public <T> List<T> readParcelableList(@NonNull List<T> list,
             @Nullable ClassLoader cl, @NonNull Class<? extends T> clazz) {
-        assertNotRecycled();
         Objects.requireNonNull(list);
         Objects.requireNonNull(clazz);
         return readParcelableListInternal(list, cl, clazz);
@@ -4396,7 +4188,6 @@
      */
     @Nullable
     public final <T> T[] createTypedArray(@NonNull Parcelable.Creator<T> c) {
-        assertNotRecycled();
         int N = readInt();
         if (N < 0) {
             return null;
@@ -4410,7 +4201,6 @@
     }
 
     public final <T> void readTypedArray(@NonNull T[] val, @NonNull Parcelable.Creator<T> c) {
-        assertNotRecycled();
         int N = readInt();
         if (N == val.length) {
             for (int i=0; i<N; i++) {
@@ -4427,7 +4217,6 @@
      */
     @Deprecated
     public final <T> T[] readTypedArray(Parcelable.Creator<T> c) {
-        assertNotRecycled();
         return createTypedArray(c);
     }
 
@@ -4444,7 +4233,6 @@
      */
     @Nullable
     public final <T> T readTypedObject(@NonNull Parcelable.Creator<T> c) {
-        assertNotRecycled();
         if (readInt() != 0) {
             return c.createFromParcel(this);
         } else {
@@ -4471,7 +4259,6 @@
      * @see #readTypedArray
      */
     public <T> void readFixedArray(@NonNull T val) {
-        assertNotRecycled();
         Class<?> componentType = val.getClass().getComponentType();
         if (componentType == boolean.class) {
             readBooleanArray((boolean[]) val);
@@ -4512,7 +4299,6 @@
      */
     public <T, S extends IInterface> void readFixedArray(@NonNull T val,
             @NonNull Function<IBinder, S> asInterface) {
-        assertNotRecycled();
         Class<?> componentType = val.getClass().getComponentType();
         if (IInterface.class.isAssignableFrom(componentType)) {
             readInterfaceArray((S[]) val, asInterface);
@@ -4539,7 +4325,6 @@
      */
     public <T, S extends Parcelable> void readFixedArray(@NonNull T val,
             @NonNull Parcelable.Creator<S> c) {
-        assertNotRecycled();
         Class<?> componentType = val.getClass().getComponentType();
         if (Parcelable.class.isAssignableFrom(componentType)) {
             readTypedArray((S[]) val, c);
@@ -4597,7 +4382,6 @@
      */
     @Nullable
     public <T> T createFixedArray(@NonNull Class<T> cls, @NonNull int... dimensions) {
-        assertNotRecycled();
         // Check if type matches with dimensions
         // If type is one-dimensional array, delegate to other creators
         // Otherwise, create an multi-dimensional array at once and then fill it with readFixedArray
@@ -4671,7 +4455,6 @@
     @Nullable
     public <T, S extends IInterface> T createFixedArray(@NonNull Class<T> cls,
             @NonNull Function<IBinder, S> asInterface, @NonNull int... dimensions) {
-        assertNotRecycled();
         // Check if type matches with dimensions
         // If type is one-dimensional array, delegate to other creators
         // Otherwise, create an multi-dimensional array at once and then fill it with readFixedArray
@@ -4732,7 +4515,6 @@
     @Nullable
     public <T, S extends Parcelable> T createFixedArray(@NonNull Class<T> cls,
             @NonNull Parcelable.Creator<S> c, @NonNull int... dimensions) {
-        assertNotRecycled();
         // Check if type matches with dimensions
         // If type is one-dimensional array, delegate to other creators
         // Otherwise, create an multi-dimensional array at once and then fill it with readFixedArray
@@ -4796,7 +4578,6 @@
      */
     public final <T extends Parcelable> void writeParcelableArray(@Nullable T[] value,
             int parcelableFlags) {
-        assertNotRecycled();
         if (value != null) {
             int N = value.length;
             writeInt(N);
@@ -4815,7 +4596,6 @@
      */
     @Nullable
     public final Object readValue(@Nullable ClassLoader loader) {
-        assertNotRecycled();
         return readValue(loader, /* clazz */ null);
     }
 
@@ -4871,7 +4651,6 @@
      */
     @Nullable
     public Object readLazyValue(@Nullable ClassLoader loader) {
-        assertNotRecycled();
         int start = dataPosition();
         int type = readInt();
         if (isLengthPrefixed(type)) {
@@ -5274,7 +5053,6 @@
     @Deprecated
     @Nullable
     public final <T extends Parcelable> T readParcelable(@Nullable ClassLoader loader) {
-        assertNotRecycled();
         return readParcelableInternal(loader, /* clazz */ null);
     }
 
@@ -5294,7 +5072,6 @@
      */
     @Nullable
     public <T> T readParcelable(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
-        assertNotRecycled();
         Objects.requireNonNull(clazz);
         return readParcelableInternal(loader, clazz);
     }
@@ -5323,7 +5100,6 @@
     @Nullable
     public final <T extends Parcelable> T readCreator(@NonNull Parcelable.Creator<?> creator,
             @Nullable ClassLoader loader) {
-        assertNotRecycled();
         if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
           Parcelable.ClassLoaderCreator<?> classLoaderCreator =
               (Parcelable.ClassLoaderCreator<?>) creator;
@@ -5351,7 +5127,6 @@
     @Deprecated
     @Nullable
     public final Parcelable.Creator<?> readParcelableCreator(@Nullable ClassLoader loader) {
-        assertNotRecycled();
         return readParcelableCreatorInternal(loader, /* clazz */ null);
     }
 
@@ -5372,7 +5147,6 @@
     @Nullable
     public <T> Parcelable.Creator<T> readParcelableCreator(
             @Nullable ClassLoader loader, @NonNull Class<T> clazz) {
-        assertNotRecycled();
         Objects.requireNonNull(clazz);
         return readParcelableCreatorInternal(loader, clazz);
     }
@@ -5495,7 +5269,6 @@
     @Deprecated
     @Nullable
     public Parcelable[] readParcelableArray(@Nullable ClassLoader loader) {
-        assertNotRecycled();
         return readParcelableArrayInternal(loader, /* clazz */ null);
     }
 
@@ -5516,7 +5289,6 @@
     @SuppressLint({"ArrayReturn", "NullableCollection"})
     @Nullable
     public <T> T[] readParcelableArray(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
-        assertNotRecycled();
         return readParcelableArrayInternal(loader, requireNonNull(clazz));
     }
 
@@ -5550,7 +5322,6 @@
     @Deprecated
     @Nullable
     public Serializable readSerializable() {
-        assertNotRecycled();
         return readSerializableInternal(/* loader */ null, /* clazz */ null);
     }
 
@@ -5567,7 +5338,6 @@
      */
     @Nullable
     public <T> T readSerializable(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
-        assertNotRecycled();
         Objects.requireNonNull(clazz);
         return readSerializableInternal(
                 loader == null ? getClass().getClassLoader() : loader, clazz);
@@ -5809,7 +5579,6 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public void readArrayMap(@NonNull ArrayMap<? super String, Object> outVal,
             @Nullable ClassLoader loader) {
-        assertNotRecycled();
         final int N = readInt();
         if (N < 0) {
             return;
@@ -5826,7 +5595,6 @@
      */
     @UnsupportedAppUsage
     public @Nullable ArraySet<? extends Object> readArraySet(@Nullable ClassLoader loader) {
-        assertNotRecycled();
         final int size = readInt();
         if (size < 0) {
             return null;
@@ -5966,7 +5734,6 @@
      * @hide For testing
      */
     public long getOpenAshmemSize() {
-        assertNotRecycled();
         return nativeGetOpenAshmemSize(mNativePtr);
     }
 
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index e728243..907d968 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -553,10 +553,9 @@
      * Foreground thread group - All threads in
      * this group are scheduled with a normal share of the CPU.
      * Value is same as constant SP_FOREGROUND of enum SchedPolicy.
-     * Not used at this level.
      * @hide
      **/
-    private static final int THREAD_GROUP_FOREGROUND = 1;
+    public static final int THREAD_GROUP_FOREGROUND = 1;
 
     /**
      * System thread group.
@@ -1315,19 +1314,6 @@
     }
 
     /**
-     * Adjust the swappiness level for a process.
-     *
-     * @param pid The process identifier to set.
-     * @param is_increased Whether swappiness should be increased or default.
-     *
-     * @return Returns true if the underlying system supports this
-     *         feature, else false.
-     *
-     * {@hide}
-     */
-    public static final native boolean setSwappiness(int pid, boolean is_increased);
-
-    /**
      * Change this process's argv[0] parameter.  This can be useful to show
      * more descriptive information in things like the 'ps' command.
      *
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
index 49b696d..7ea521e 100644
--- a/core/java/android/os/ServiceManagerNative.java
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -50,7 +50,8 @@
 class ServiceManagerProxy implements IServiceManager {
     public ServiceManagerProxy(IBinder remote) {
         mRemote = remote;
-        mServiceManager = IServiceManager.Stub.asInterface(this.getNativeServiceManager());
+        mServiceManager = IServiceManager.Stub.asInterface(
+            Binder.allowBlocking(this.getNativeServiceManager()));
     }
 
     public IBinder asBinder() {
diff --git a/core/java/android/os/TestLooperManager.java b/core/java/android/os/TestLooperManager.java
index e673e17..e216992 100644
--- a/core/java/android/os/TestLooperManager.java
+++ b/core/java/android/os/TestLooperManager.java
@@ -95,8 +95,8 @@
     }
 
     /**
-     * Returns the next message that should be executed by this queue, and removes it from the
-     * queue. If the queue is empty or no messages are deliverable, returns null.
+     * Retrieves and removes the next message that should be executed by this queue.
+     * If the queue is empty or no messages are deliverable, returns null.
      * This method never blocks.
      *
      * <p>Callers should always call {@link #recycle(Message)} on the message when all interactions
@@ -104,15 +104,19 @@
      */
     @FlaggedApi(Flags.FLAG_MESSAGE_QUEUE_TESTABILITY)
     @Nullable
-    public Message pop() {
+    public Message poll() {
         checkReleased();
-        return mQueue.popForTest();
+        return mQueue.pollForTest();
     }
 
     /**
-     * Returns the values of {@link Message#when} of the next message that should be executed by
-     * this queue. If the queue is empty or no messages are deliverable, returns null.
+     * Retrieves, but does not remove, the values of {@link Message#when} of next message that
+     * should be executed by this queue.
+     * If the queue is empty or no messages are deliverable, returns null.
      * This method never blocks.
+     *
+     * <p>Callers should always call {@link #recycle(Message)} on the message when all interactions
+     * with it have completed.
      */
     @FlaggedApi(Flags.FLAG_MESSAGE_QUEUE_TESTABILITY)
     @SuppressWarnings("AutoBoxing")  // box the primitive long, or return null to indicate no value
@@ -123,6 +127,18 @@
     }
 
     /**
+     * Checks whether the Looper is currently blocked on a sync barrier.
+     *
+     * A Looper is blocked on a sync barrier if there is a Message in the Looper's
+     * queue that is ready for execution but is behind a sync barrier
+     */
+    @FlaggedApi(Flags.FLAG_MESSAGE_QUEUE_TESTABILITY)
+    public boolean isBlockedOnSyncBarrier() {
+        checkReleased();
+        return mQueue.isBlockedOnSyncBarrier();
+    }
+
+    /**
      * Releases the looper to continue standard looping and processing of messages, no further
      * interactions with TestLooperManager will be allowed after release() has been called.
      */
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 7e73a5d..b9f2cfc 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -6501,7 +6501,11 @@
      * @hide
      */
     public static final void invalidateCacheOnUserDataChanged() {
-        if (android.multiuser.Flags.cacheProfilesReadOnly()) {
+        if (android.multiuser.Flags.cacheProfilesReadOnly()
+                || android.multiuser.Flags.cacheUserInfoReadOnly()) {
+            // TODO(b/383175685): Rename the invalidation call to make it clearer that it
+            // invalidates the caches for both getProfiles and getUserInfo (since they both use the
+            // same user_manager_user_data CachedProperty.api).
             UserManagerCache.invalidateProfiles();
         }
     }
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index 2c4883f..af96ccf 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -57,7 +57,7 @@
     is_exported: true
     is_fixed_read_only: true
     namespace: "permissions"
-    description: "enable enhanced confirmation incall apis"
+    description: "DEPRECATED, does not gate any apis"
     bug: "364535720"
 }
 
@@ -492,3 +492,13 @@
     description: "This flag is used to enable the role system_vendor_intelligence"
     bug: "377553620"
 }
+
+flag {
+    name: "fine_power_monitor_permission"
+    is_fixed_read_only: true
+    is_exported: true
+    namespace: "permissions"
+    description: "Add support for fine-grained PowerMonitor readings"
+    bug: "341941666"
+}
+
diff --git a/core/java/android/provider/flags.aconfig b/core/java/android/provider/flags.aconfig
index fff5363..a80be53 100644
--- a/core/java/android/provider/flags.aconfig
+++ b/core/java/android/provider/flags.aconfig
@@ -24,14 +24,6 @@
     bug: "290696572"
 }
 
-flag {
-    name: "backup_tasks_settings_screen"
-    is_exported: true
-    namespace: "backstage_power"
-    description: "Add a new settings page for the RUN_BACKUP_JOBS permission."
-    bug: "320563660"
-}
-
 # OWNER = tgunn TARGET=25Q1
 flag {
     name: "allow_config_maximum_call_log_entries_per_sim"
diff --git a/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.java b/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.java
index 64a3f0f..568a6d7 100644
--- a/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.java
+++ b/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.java
@@ -38,23 +38,30 @@
     /**
      * Client message associated with the request to disable secure lock on the device. This message
      * will be shown on the device when secure lock mode is disabled.
+     *
+     * Since this text is shown in a restricted lockscreen state, typeface properties such as color,
+     * font weight, or other formatting may not be honored.
      */
-    private final @NonNull String mMessage;
+    private final @NonNull CharSequence mMessage;
 
     /**
      * Creates DisableSecureLockDeviceParams with the given params.
      *
      * @param message Allows clients to pass in a message with information about the request to
      *                disable secure lock on the device. This message will be shown to the user when
-     *                secure lock mode is disabled. If an empty string is provided, it will default
-     *                to a system-defined string (e.g. "Secure lock mode has been disabled.")
+     *                secure lock mode is disabled. If an empty CharSequence is provided, it will
+     *                default to a system-defined CharSequence (e.g. "Secure lock mode has been
+     *                disabled.")
+     *
+     *                Since this text is shown in a restricted lockscreen state, typeface properties
+     *                such as color, font weight, or other formatting may not be honored.
      */
-    public DisableSecureLockDeviceParams(@NonNull String message) {
+    public DisableSecureLockDeviceParams(@NonNull CharSequence message) {
         mMessage = message;
     }
 
     private DisableSecureLockDeviceParams(@NonNull Parcel in) {
-        mMessage = Objects.requireNonNull(in.readString8());
+        mMessage = Objects.requireNonNull(in.readCharSequence());
     }
 
     public static final @NonNull Creator<DisableSecureLockDeviceParams> CREATOR =
@@ -77,6 +84,6 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeString8(mMessage);
+        dest.writeCharSequence(mMessage);
     }
 }
diff --git a/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.java b/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.java
index 1d72772..dfa391f 100644
--- a/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.java
+++ b/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.java
@@ -38,23 +38,30 @@
     /**
      * Client message associated with the request to enable secure lock on the device. This message
      * will be shown on the device when secure lock mode is enabled.
+     *
+     * Since this text is shown in a restricted lockscreen state, typeface properties such as color,
+     * font weight, or other formatting may not be honored.
      */
-    private final @NonNull String mMessage;
+    private final @NonNull CharSequence mMessage;
 
     /**
      * Creates EnableSecureLockDeviceParams with the given params.
      *
      * @param message Allows clients to pass in a message with information about the request to
      *                enable secure lock on the device. This message will be shown to the user when
-     *                secure lock mode is enabled. If an empty string is provided, it will default
-     *                to a system-defined string (e.g. "Device is securely locked remotely.")
+     *                secure lock mode is enabled. If an empty CharSequence is provided, it will
+     *                default to a system-defined CharSequence (e.g. "Device is securely locked
+     *                remotely.")
+     *
+     *                Since this text is shown in a restricted lockscreen state, typeface properties
+     *                such as color, font weight, or other formatting may not be honored.
      */
-    public EnableSecureLockDeviceParams(@NonNull String message) {
+    public EnableSecureLockDeviceParams(@NonNull CharSequence message) {
         mMessage = message;
     }
 
     private EnableSecureLockDeviceParams(@NonNull Parcel in) {
-        mMessage = Objects.requireNonNull(in.readString8());
+        mMessage = Objects.requireNonNull(in.readCharSequence());
     }
 
     public static final @NonNull Creator<EnableSecureLockDeviceParams> CREATOR =
@@ -77,6 +84,6 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeString8(mMessage);
+        dest.writeCharSequence(mMessage);
     }
 }
diff --git a/core/java/android/service/autofill/augmented/FillWindow.java b/core/java/android/service/autofill/augmented/FillWindow.java
index 0ce040d..d42ec7c 100644
--- a/core/java/android/service/autofill/augmented/FillWindow.java
+++ b/core/java/android/service/autofill/augmented/FillWindow.java
@@ -17,6 +17,7 @@
 
 import static android.service.autofill.augmented.AugmentedAutofillService.sDebug;
 import static android.service.autofill.augmented.AugmentedAutofillService.sVerbose;
+import static android.service.autofill.Flags.addAccessibilityTitleForAugmentedAutofillDropdown;
 
 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 
@@ -36,6 +37,7 @@
 import android.view.autofill.IAutofillWindowPresenter;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.R;
 
 import dalvik.system.CloseGuard;
 
@@ -208,6 +210,12 @@
             if (mWm != null && mFillView != null) {
                 try {
                     p.flags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
+                    if (addAccessibilityTitleForAugmentedAutofillDropdown()) {
+                        p.accessibilityTitle =
+                            mFillView
+                                    .getContext()
+                                    .getString(R.string.autofill_picker_accessibility_title);
+                    }
                     if (!mShowing) {
                         mWm.addView(mFillView, p);
                         mShowing = true;
diff --git a/services/core/java/com/android/server/notification/RateEstimator.java b/core/java/android/service/notification/RateEstimator.java
similarity index 92%
rename from services/core/java/com/android/server/notification/RateEstimator.java
rename to core/java/android/service/notification/RateEstimator.java
index eda96ac..04789c1 100644
--- a/services/core/java/com/android/server/notification/RateEstimator.java
+++ b/core/java/android/service/notification/RateEstimator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 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.
@@ -11,10 +11,10 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
 
-package com.android.server.notification;
+package android.service.notification;
 
 
 /**
@@ -22,7 +22,7 @@
  *
  * {@hide}
  */
-class RateEstimator {
+public class RateEstimator {
     private static final double RATE_ALPHA = 0.7;
     private static final double MINIMUM_DT = 0.0005;
 
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index cb72b97..6dc82c4 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -678,7 +678,7 @@
      * @return true if a and b are equal
      */
     @android.ravenwood.annotation.RavenwoodKeep
-    public static boolean equals(CharSequence a, CharSequence b) {
+    public static boolean equals(@Nullable CharSequence a, @Nullable CharSequence b) {
         if (a == b) return true;
         int length;
         if (a != null && b != null && (length = a.length()) == b.length()) {
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 802bddd..1ea226b 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -19,6 +19,7 @@
 import static android.Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE;
 import static android.Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS;
 import static android.hardware.flags.Flags.FLAG_OVERLAYPROPERTIES_CLASS_API;
+import static android.util.TypedValue.COMPLEX_UNIT_DIP;
 
 import static com.android.server.display.feature.flags.Flags.FLAG_ENABLE_GET_SUPPORTED_REFRESH_RATES;
 import static com.android.server.display.feature.flags.Flags.FLAG_HIGHEST_HDR_SDR_RATIO_API;
@@ -58,6 +59,7 @@
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.Log;
+import android.util.TypedValue;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -1048,6 +1050,19 @@
     }
 
     /**
+     * Returns the smallest size of the display in dp
+     * @hide
+     */
+    public float getMinSizeDimensionDp() {
+        synchronized (mLock) {
+            updateDisplayInfoLocked();
+            mDisplayInfo.getAppMetrics(mTempMetrics);
+            return TypedValue.deriveDimension(COMPLEX_UNIT_DIP,
+                    Math.min(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight), mTempMetrics);
+        }
+    }
+
+    /**
      * @deprecated Use {@link WindowMetrics#getBounds#width()} instead.
      */
     @Deprecated
diff --git a/core/java/android/view/EventLogTags.logtags b/core/java/android/view/EventLogTags.logtags
index f379293..95894fa 100644
--- a/core/java/android/view/EventLogTags.logtags
+++ b/core/java/android/view/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
 
 option java_package android.view
 
@@ -35,7 +35,7 @@
 # 6: Percent
 # Default value for data of type int/long is 2 (bytes).
 #
-# See system/core/logcat/event.logtags for the master copy of the tags.
+# See system/logging/logcat/event.logtags for the master copy of the tags.
 
 # 32000 - 32999 reserved for input method framework
 # IME animation is started.
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 5da4985..072a037 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -933,6 +933,27 @@
     void detachWindowContext(IBinder clientToken);
 
     /**
+     * Reparents the {@link android.window.WindowContext} to the
+     * {@link com.android.server.wm.DisplayArea} on another display.
+     * This method also reparent the WindowContext associated WindowToken to another display if
+     * necessary.
+     * <p>
+     * {@code type} and {@code options} must be the same as the previous call of
+     * {@link #attachWindowContextToDisplayArea} on the same Context otherwise this will fail
+     * silently.
+     *
+     * @param appThread the process that the window context is on.
+     * @param clientToken the window context's token
+     * @param type The window type of the WindowContext
+     * @param displayId The new display id this context windows should be parented to
+     * @param options Bundle the context was created with
+     *
+     * @return True if the operation was successful, False otherwise.
+     */
+    boolean reparentWindowContextToDisplayArea(in IApplicationThread appThread,
+                IBinder clientToken, int displayId);
+
+    /**
      * Registers a listener, which is to be called whenever cross-window blur is enabled/disabled.
      *
      * @param listener the listener to be registered
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 67050e0..213ece0 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -296,8 +296,8 @@
             @SoftInputModeFlags int softInputMode, int windowFlags) {
         final int softInputAdjustMode = softInputMode & SOFT_INPUT_MASK_ADJUST;
         final int visibleInsetsTypes = softInputAdjustMode != SOFT_INPUT_ADJUST_NOTHING
-                ? systemBars() | ime()
-                : systemBars();
+                ? systemBars() | displayCutout() | ime()
+                : systemBars() | displayCutout();
         @InsetsType int forceConsumingTypes = 0;
         Insets insets = Insets.NONE;
         for (int i = mSources.size() - 1; i >= 0; i--) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 0681745..d13f0e2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -17184,7 +17184,7 @@
         final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
         final WindowMetrics metrics = windowManager.getMaximumWindowMetrics();
         final Insets insets = metrics.getWindowInsets().getInsets(
-                WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout());
+                WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout());
         outRect.set(metrics.getBounds());
         outRect.inset(insets);
         outRect.offsetTo(0, 0);
@@ -28277,28 +28277,14 @@
         mPrivateFlags |= PFLAG_FORCE_LAYOUT;
         mPrivateFlags |= PFLAG_INVALIDATED;
 
-        if (mParent != null) {
-            if (!mParent.isLayoutRequested()) {
-                mParent.requestLayout();
-            } else {
-                clearMeasureCacheOfAncestors();
-            }
+        if (mParent != null && !mParent.isLayoutRequested()) {
+            mParent.requestLayout();
         }
         if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == this) {
             mAttachInfo.mViewRequestingLayout = null;
         }
     }
 
-    private void clearMeasureCacheOfAncestors() {
-        ViewParent parent = mParent;
-        while (parent instanceof View view) {
-            if (view.mMeasureCache != null) {
-                view.mMeasureCache.clear();
-            }
-            parent = view.mParent;
-        }
-    }
-
     /**
      * Forces this view to be laid out during the next layout pass.
      * This method does not call requestLayout() or forceLayout()
@@ -28654,10 +28640,8 @@
      */
     @RemotableViewMethod
     public void setMinimumHeight(int minHeight) {
-        if (mMinHeight != minHeight) {
-            mMinHeight = minHeight;
-            requestLayout();
-        }
+        mMinHeight = minHeight;
+        requestLayout();
     }
 
     /**
@@ -28687,10 +28671,8 @@
      */
     @RemotableViewMethod
     public void setMinimumWidth(int minWidth) {
-        if (mMinWidth != minWidth) {
-            mMinWidth = minWidth;
-            requestLayout();
-        }
+        mMinWidth = minWidth;
+        requestLayout();
 
     }
 
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 1596b85..c1b92ee3 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import static android.adpf.Flags.adpfViewrootimplActionDownBoost;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.content.pm.ActivityInfo.OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS;
 import static android.graphics.HardwareRenderer.SYNC_CONTEXT_IS_STOPPED;
@@ -7977,8 +7978,9 @@
         }
 
         private boolean moveFocusToAdjacentWindow(@FocusDirection int direction) {
-            if (getConfiguration().windowConfiguration.getWindowingMode()
-                    != WINDOWING_MODE_MULTI_WINDOW) {
+            final int windowingMode = getConfiguration().windowConfiguration.getWindowingMode();
+            if (windowingMode != WINDOWING_MODE_MULTI_WINDOW
+                    && windowingMode != WINDOWING_MODE_FREEFORM) {
                 return false;
             }
             try {
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 1de0474..60e528c 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -26,6 +26,7 @@
 import static android.service.autofill.FillRequest.FLAG_VIEW_NOT_FOCUSED;
 import static android.service.autofill.FillRequest.FLAG_VIEW_REQUESTS_CREDMAN_SERVICE;
 import static android.service.autofill.Flags.FLAG_FILL_DIALOG_IMPROVEMENTS;
+import static android.service.autofill.Flags.improveFillDialogAconfig;
 import static android.service.autofill.Flags.relayoutFix;
 import static android.view.ContentInfo.SOURCE_AUTOFILL;
 import static android.view.autofill.Helper.sDebug;
@@ -787,6 +788,11 @@
 
     private AutofillStateFingerprint mAutofillStateFingerprint;
 
+    /**
+     * Whether improveFillDialog feature is enabled or not.
+     */
+    private boolean mImproveFillDialogEnabled;
+
     /** @hide */
     public interface AutofillClient {
         /**
@@ -1017,6 +1023,17 @@
         mRelayoutFix = relayoutFix() && AutofillFeatureFlags.enableRelayoutFixes();
         mRelativePositionForRelayout = AutofillFeatureFlags.enableRelativeLocationForRelayout();
         mIsCredmanIntegrationEnabled = Flags.autofillCredmanIntegration();
+        mImproveFillDialogEnabled =
+                improveFillDialogAconfig() && AutofillFeatureFlags.isImproveFillDialogEnabled();
+    }
+
+    /**
+     * Whether improvement to fill dialog is enabled.
+     *
+     * @hide
+     */
+    public boolean isImproveFillDialogEnabled() {
+        return mImproveFillDialogEnabled;
     }
 
     /**
@@ -1679,6 +1696,11 @@
 
     private void notifyViewReadyInner(AutofillId id, @Nullable String[] autofillHints,
             boolean isCredmanRequested) {
+        if (isImproveFillDialogEnabled() && !isCredmanRequested) {
+            // We do not want to send pre-trigger request.
+            // TODO(b/377868687): verify if we can remove the flow for isCredmanRequested too.
+            return;
+        }
         if (sDebug) {
             Log.d(TAG, "notifyViewReadyInner:" + id);
         }
@@ -2046,6 +2068,34 @@
     }
 
     /**
+     * Notify autofill system that IME animation has started
+     * @param startTimeMs start time as measured by SystemClock.elapsedRealtime()
+     */
+    void notifyImeAnimationStart(long startTimeMs) {
+        try {
+            mService.notifyImeAnimationStart(mSessionId, startTimeMs, mContext.getUserId());
+        } catch (RemoteException e) {
+            // The failure could be a consequence of something going wrong on the
+            // server side. Just log the exception and move-on.
+            Log.w(TAG, "notifyImeAnimationStart(): RemoteException caught but ignored " + e);
+        }
+    }
+
+    /**
+     * Notify autofill system that IME animation has ended
+     * @param endTimeMs end time as measured by SystemClock.elapsedRealtime()
+     */
+    void notifyImeAnimationEnd(long endTimeMs) {
+        try {
+            mService.notifyImeAnimationEnd(mSessionId, endTimeMs, mContext.getUserId());
+        } catch (RemoteException e) {
+            // The failure could be a consequence of something going wrong on the
+            // server side. Just log the exception and move-on.
+            Log.w(TAG, "notifyImeAnimationStart(): RemoteException caught but ignored " + e);
+        }
+    }
+
+    /**
      * Called when a virtual view that supports autofill is exited.
      *
      * @param view the virtual view parent.
@@ -4050,6 +4100,10 @@
     @FlaggedApi(FLAG_FILL_DIALOG_IMPROVEMENTS)
     @Deprecated
     public boolean showAutofillDialog(@NonNull View view) {
+        if (isImproveFillDialogEnabled()) {
+            Log.i(TAG, "showAutofillDialog() return false due to improve fill dialog");
+            return false;
+        }
         Objects.requireNonNull(view);
         if (shouldShowAutofillDialog(view, view.getAutofillId())) {
             mShowAutofillDialogCalled = true;
@@ -4093,6 +4147,10 @@
     @FlaggedApi(FLAG_FILL_DIALOG_IMPROVEMENTS)
     @Deprecated
     public boolean showAutofillDialog(@NonNull View view, int virtualId) {
+        if (isImproveFillDialogEnabled()) {
+            Log.i(TAG, "showAutofillDialog() return false due to improve fill dialog");
+            return false;
+        }
         Objects.requireNonNull(view);
         if (shouldShowAutofillDialog(view, getAutofillId(view, virtualId))) {
             mShowAutofillDialogCalled = true;
@@ -4117,7 +4175,7 @@
             return false;
         }
 
-        if (getImeStateFlag(view) == FLAG_IME_SHOWING) {
+        if (getImeStateFlag(view) == FLAG_IME_SHOWING && !isImproveFillDialogEnabled()) {
             // IME is showing
             return false;
         }
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index f67405f..28f8577 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -70,4 +70,6 @@
     void notifyNotExpiringResponseDuringAuth(int sessionId, int userId);
     void notifyViewEnteredIgnoredDuringAuthCount(int sessionId, int userId);
     void setAutofillIdsAttemptedForRefill(int sessionId, in List<AutofillId> ids, int userId);
+    void notifyImeAnimationStart(int sessionId, long startTimeMs, int userId);
+    void notifyImeAnimationEnd(int sessionId, long endTimeMs, int userId);
 }
diff --git a/core/java/android/view/flags/scroll_capture.aconfig b/core/java/android/view/flags/scroll_capture.aconfig
index 9080b16..6dccbad 100644
--- a/core/java/android/view/flags/scroll_capture.aconfig
+++ b/core/java/android/view/flags/scroll_capture.aconfig
@@ -11,3 +11,12 @@
     }
 }
 
+flag {
+    name: "scroll_capture_relax_scroll_view_criteria"
+    namespace: "systemui"
+    description: "Treat all custom ViewGroups which support scrollTo as ScrollView"
+    bug: "189827634"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 6d89f3d..f82e5f9 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -948,7 +948,7 @@
                             // requestedVisibleTypes of WindowInsetsController by hiding the IME
                             final var statsToken = ImeTracker.forLogging().onStart(
                                     ImeTracker.TYPE_HIDE, ImeTracker.ORIGIN_CLIENT,
-                                    SoftInputShowHideReason.REASON_HIDE_WINDOW_LOST_FOCUS,
+                                    SoftInputShowHideReason.HIDE_WINDOW_LOST_FOCUS,
                                     false /* fromUser */);
                             if (DEBUG) {
                                 Log.d(TAG, "onWindowLostFocus, hiding IME because "
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index b606340..b929324 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -16,13 +16,20 @@
 
 package android.view.textclassifier;
 
+import static android.Manifest.permission.ACCESS_TEXT_CLASSIFIER_BY_TYPE;
+
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.os.Build;
 import android.os.ServiceManager;
+import android.permission.flags.Flags;
 import android.view.textclassifier.TextClassifier.TextClassifierType;
 
 import com.android.internal.annotations.GuardedBy;
@@ -115,6 +122,29 @@
         }
     }
 
+    /**
+     * Returns a specific type of text classifier.
+     * If the specified text classifier cannot be found, this returns {@link TextClassifier#NO_OP}.
+     * <p>
+     *
+     * @see TextClassifier#CLASSIFIER_TYPE_SELF_PROVIDED
+     * @see TextClassifier#CLASSIFIER_TYPE_DEVICE_DEFAULT
+     * @see TextClassifier#CLASSIFIER_TYPE_ANDROID_DEFAULT
+     * @hide
+     */
+    @SystemApi
+    @NonNull
+    @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+    @RequiresPermission(ACCESS_TEXT_CLASSIFIER_BY_TYPE)
+    public TextClassifier getClassifier(@TextClassifierType int type) {
+        if (mContext.checkCallingOrSelfPermission(ACCESS_TEXT_CLASSIFIER_BY_TYPE)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException(
+                    "Caller does not have permission " + ACCESS_TEXT_CLASSIFIER_BY_TYPE);
+        }
+        return getTextClassifier(type);
+    }
+
     private TextClassificationConstants getSettings() {
         synchronized (mLock) {
             if (mSettings == null) {
diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java
index ef50045..59afdac 100644
--- a/core/java/android/view/textclassifier/TextClassifier.java
+++ b/core/java/android/view/textclassifier/TextClassifier.java
@@ -16,16 +16,20 @@
 
 package android.view.textclassifier;
 
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.StringDef;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
 import android.annotation.WorkerThread;
 import android.os.LocaleList;
 import android.os.Looper;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.permission.flags.Flags;
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.style.URLSpan;
@@ -63,11 +67,6 @@
     /** @hide */
     String LOG_TAG = "androidtc";
 
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {LOCAL, SYSTEM, DEFAULT_SYSTEM})
-    @interface TextClassifierType {}  // TODO: Expose as system APIs.
     /** Specifies a TextClassifier that runs locally in the app's process. @hide */
     int LOCAL = 0;
     /** Specifies a TextClassifier that runs in the system process and serves all apps. @hide */
@@ -76,8 +75,33 @@
     int DEFAULT_SYSTEM = 2;
 
     /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {CLASSIFIER_TYPE_SELF_PROVIDED, CLASSIFIER_TYPE_DEVICE_DEFAULT,
+            CLASSIFIER_TYPE_ANDROID_DEFAULT})
+    @interface TextClassifierType {
+    }
+    /** Specifies a TextClassifier that runs locally in the app's process. @hide */
+    @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+    @SystemApi
+    int CLASSIFIER_TYPE_SELF_PROVIDED = LOCAL;
+    /**
+     * Specifies a TextClassifier that is set as the default on this particular device. This may be
+     * the same as CLASSIFIER_TYPE_DEVICE_DEFAULT, unless set otherwise by the device manufacturer.
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+    @SystemApi
+    int CLASSIFIER_TYPE_DEVICE_DEFAULT = SYSTEM;
+    /** Specifies the TextClassifier that is provided by Android. @hide */
+    @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+    @SystemApi
+    int CLASSIFIER_TYPE_ANDROID_DEFAULT = DEFAULT_SYSTEM;
+
+    /** @hide */
+    @SuppressLint("SwitchIntDef")
     static String typeToString(@TextClassifierType int type) {
-        switch (type) {
+        int unflaggedType = type;
+        switch (unflaggedType) {
             case LOCAL:
                 return "Local";
             case SYSTEM:
@@ -108,6 +132,9 @@
     String TYPE_DATE_TIME = "datetime";
     /** Flight number in IATA format. */
     String TYPE_FLIGHT_NUMBER = "flight";
+    /** Onetime password. */
+    @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+    String TYPE_OTP = "otp";
     /**
      * Word that users may be interested to look up for meaning.
      * @hide
@@ -126,7 +153,8 @@
             TYPE_DATE,
             TYPE_DATE_TIME,
             TYPE_FLIGHT_NUMBER,
-            TYPE_DICTIONARY
+            TYPE_DICTIONARY,
+            TYPE_OTP
     })
     @interface EntityType {}
 
@@ -198,6 +226,16 @@
     String EXTRA_FROM_TEXT_CLASSIFIER = "android.view.textclassifier.extra.FROM_TEXT_CLASSIFIER";
 
     /**
+     * Extra specifying the package name of the app from which the text to be classified originated.
+     *
+     * For example, a notification assistant might use TextClassifier, but the notification
+     * content could originate from a different app. This key allows you to provide
+     * the package name of that source app.
+     */
+    @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+    String EXTRA_TEXT_ORIGIN_PACKAGE = "android.view.textclassifier.extra.TEXT_ORIGIN_PACKAGE";
+
+    /**
      * Returns suggested text selection start and end indices, recognized entity types, and their
      * associated confidence scores. The entity types are ordered from highest to lowest scoring.
      *
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 0721fd3..fc3014a 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -3737,7 +3737,7 @@
                     atEdge = trackMotionScroll(deltaY, incrementalDeltaY);
 
                     // TODO: b/360198915 - Add unit testing for using ScrollFeedbackProvider
-                    if (enableScrollFeedbackForTouch()) {
+                    if (vtev != null && enableScrollFeedbackForTouch()) {
                         initHapticScrollFeedbackProviderIfNotExists();
                         mHapticScrollFeedbackProvider.onScrollProgress(
                                 vtev.getDeviceId(), vtev.getSource(), MotionEvent.AXIS_Y,
@@ -3779,7 +3779,7 @@
                                     mTouchMode = TOUCH_MODE_OVERSCROLL;
                                 }
 
-                                if (enableScrollFeedbackForTouch()) {
+                                if (vtev != null && enableScrollFeedbackForTouch()) {
                                     initHapticScrollFeedbackProviderIfNotExists();
                                     mHapticScrollFeedbackProvider.onScrollLimit(
                                             vtev.getDeviceId(), vtev.getSource(),
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 2cd3901..9fe3fd6 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -20,6 +20,7 @@
 import static android.appwidget.flags.Flags.FLAG_REMOTE_VIEWS_PROTO;
 import static android.appwidget.flags.Flags.drawDataParcel;
 import static android.appwidget.flags.Flags.remoteAdapterConversion;
+import static android.content.res.Flags.FLAG_SELF_TARGETING_ANDROID_RESOURCE_FRRO;
 import static android.util.TypedValue.TYPE_INT_COLOR_ARGB8;
 import static android.util.proto.ProtoInputStream.NO_MORE_FIELDS;
 import static android.view.inputmethod.Flags.FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR;
@@ -47,6 +48,7 @@
 import android.app.PendingIntent;
 import android.app.RemoteInput;
 import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager.ServiceCollectionCache;
 import android.appwidget.flags.Flags;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
@@ -54,7 +56,6 @@
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.IntentSender;
-import android.content.ServiceConnection;
 import android.content.om.FabricatedOverlay;
 import android.content.om.OverlayInfo;
 import android.content.om.OverlayManager;
@@ -82,7 +83,6 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.CancellationSignal;
-import android.os.IBinder;
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
@@ -127,8 +127,8 @@
 import com.android.internal.R;
 import com.android.internal.util.Preconditions;
 import com.android.internal.widget.IRemoteViewsFactory;
-import com.android.internal.widget.remotecompose.core.operations.Theme;
 import com.android.internal.widget.remotecompose.core.CoreDocument;
+import com.android.internal.widget.remotecompose.core.operations.Theme;
 import com.android.internal.widget.remotecompose.player.RemoteComposeDocument;
 import com.android.internal.widget.remotecompose.player.RemoteComposePlayer;
 
@@ -1391,8 +1391,10 @@
     /**
      * @hide
      */
-    public CompletableFuture<Void> collectAllIntents(int bitmapSizeLimit) {
-        return mCollectionCache.collectAllIntentsNoComplete(this, bitmapSizeLimit);
+    public CompletableFuture<Void> collectAllIntents(int bitmapSizeLimit,
+            @NonNull ServiceCollectionCache collectionCache) {
+        return mCollectionCache.collectAllIntentsNoComplete(this, bitmapSizeLimit,
+                collectionCache);
     }
 
     private class RemoteCollectionCache {
@@ -1446,7 +1448,8 @@
         }
 
         public @NonNull CompletableFuture<Void> collectAllIntentsNoComplete(
-                @NonNull RemoteViews inViews, int bitmapSizeLimit) {
+                @NonNull RemoteViews inViews, int bitmapSizeLimit,
+                @NonNull ServiceCollectionCache collectionCache) {
             SparseArray<Intent> idToIntentMapping = new SparseArray<>();
             // Collect the number of uinque Intent (which is equal to the number of new connections
             // to make) for size allocation and exclude certain collections from being written to
@@ -1478,7 +1481,7 @@
                     / numOfIntents;
 
             return connectAllUniqueIntents(individualSize, individualBitmapSizeLimit,
-                    idToIntentMapping);
+                    idToIntentMapping, collectionCache);
         }
 
         private void collectAllIntentsInternal(@NonNull RemoteViews inViews,
@@ -1544,13 +1547,14 @@
         }
 
         private @NonNull CompletableFuture<Void> connectAllUniqueIntents(int individualSize,
-                int individualBitmapSize, @NonNull SparseArray<Intent> idToIntentMapping) {
+                int individualBitmapSize, @NonNull SparseArray<Intent> idToIntentMapping,
+                @NonNull ServiceCollectionCache collectionCache) {
             List<CompletableFuture<Void>> intentFutureList = new ArrayList<>();
             for (int i = 0; i < idToIntentMapping.size(); i++) {
                 String currentIntentUri = mIdToUriMapping.get(idToIntentMapping.keyAt(i));
                 Intent currentIntent = idToIntentMapping.valueAt(i);
                 intentFutureList.add(getItemsFutureFromIntentWithTimeout(currentIntent,
-                        individualSize, individualBitmapSize)
+                        individualSize, individualBitmapSize, collectionCache)
                         .thenAccept(items -> {
                             items.setHierarchyRootData(getHierarchyRootData());
                             mUriToCollectionMapping.put(currentIntentUri, items);
@@ -1561,7 +1565,8 @@
         }
 
         private static CompletableFuture<RemoteCollectionItems> getItemsFutureFromIntentWithTimeout(
-                Intent intent, int individualSize, int individualBitmapSize) {
+                Intent intent, int individualSize, int individualBitmapSize,
+                @NonNull ServiceCollectionCache collectionCache) {
             if (intent == null) {
                 Log.e(LOG_TAG, "Null intent received when generating adapter future");
                 return CompletableFuture.completedFuture(new RemoteCollectionItems
@@ -1581,39 +1586,24 @@
                 return result;
             }
 
-            context.bindService(intent, Context.BindServiceFlags.of(Context.BIND_AUTO_CREATE),
-                    result.defaultExecutor(), new ServiceConnection() {
-                        @Override
-                        public void onServiceConnected(ComponentName componentName,
-                                IBinder iBinder) {
-                            RemoteCollectionItems items;
-                            try {
-                                items = IRemoteViewsFactory.Stub.asInterface(iBinder)
-                                        .getRemoteCollectionItems(individualSize,
-                                                individualBitmapSize);
-                            } catch (RemoteException re) {
-                                items = new RemoteCollectionItems.Builder().build();
-                                Log.e(LOG_TAG, "Error getting collection items from the"
-                                        + " factory", re);
-                            } finally {
-                                context.unbindService(this);
-                            }
+            collectionCache.connectAndConsume(intent, iBinder -> {
+                RemoteCollectionItems items;
+                try {
+                    items = IRemoteViewsFactory.Stub.asInterface(iBinder)
+                            .getRemoteCollectionItems(individualSize,
+                                    individualBitmapSize);
+                } catch (RemoteException re) {
+                    items = new RemoteCollectionItems.Builder().build();
+                    Log.e(LOG_TAG, "Error getting collection items from the"
+                            + " factory", re);
+                }
 
-                            if (items == null) {
-                                items = new RemoteCollectionItems.Builder().build();
-                            }
+                if (items == null) {
+                    items = new RemoteCollectionItems.Builder().build();
+                }
 
-                            result.complete(items);
-                        }
-
-                        @Override
-                        public void onNullBinding(ComponentName name) {
-                            context.unbindService(this);
-                        }
-
-                        @Override
-                        public void onServiceDisconnected(ComponentName componentName) { }
-                    });
+                result.complete(items);
+            }, result.defaultExecutor());
 
             result.completeOnTimeout(
                     new RemoteCollectionItems.Builder().build(),
@@ -8709,6 +8699,7 @@
          *
          * @hide
          */
+        @FlaggedApi(FLAG_SELF_TARGETING_ANDROID_RESOURCE_FRRO)
         @Nullable
         public static ColorResources createWithOverlay(Context context,
                 SparseIntArray colorMapping) {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index d7750bd..71a832d 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -18,6 +18,7 @@
 
 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.graphics.Paint.NEW_FONT_VARIATION_MANAGEMENT;
 import static android.view.ContentInfo.FLAG_CONVERT_TO_PLAIN_TEXT;
 import static android.view.ContentInfo.SOURCE_AUTOFILL;
 import static android.view.ContentInfo.SOURCE_CLIPBOARD;
@@ -5542,7 +5543,21 @@
                         && fontVariationSettings.equals(existingSettings))) {
             return true;
         }
-        boolean effective = mTextPaint.setFontVariationSettings(fontVariationSettings);
+
+        final boolean useFontVariationStore = Flags.typefaceRedesignReadonly()
+                && CompatChanges.isChangeEnabled(NEW_FONT_VARIATION_MANAGEMENT);
+        boolean effective;
+        if (useFontVariationStore) {
+            if (mFontWeightAdjustment != 0
+                    && mFontWeightAdjustment != Configuration.FONT_WEIGHT_ADJUSTMENT_UNDEFINED) {
+                mTextPaint.setFontVariationSettings(fontVariationSettings, mFontWeightAdjustment);
+            } else {
+                mTextPaint.setFontVariationSettings(fontVariationSettings);
+            }
+            effective = true;
+        } else {
+            effective = mTextPaint.setFontVariationSettings(fontVariationSettings);
+        }
 
         if (effective && mLayout != null) {
             nullLayouts();
@@ -10114,6 +10129,10 @@
                     outAttrs.extras.putBoolean(
                             STYLUS_HANDWRITING_ENABLED_ANDROIDX_EXTRAS_KEY, handwritingEnabled);
                 }
+                if (android.view.inputmethod.Flags.writingTools()) {
+                    // default to same behavior as isSuggestionsEnabled().
+                    outAttrs.setWritingToolsEnabled(isSuggestionsEnabled());
+                }
                 ArrayList<Class<? extends HandwritingGesture>> gestures = new ArrayList<>();
                 gestures.add(SelectGesture.class);
                 gestures.add(SelectRangeGesture.class);
diff --git a/core/java/android/window/TaskSnapshot.java b/core/java/android/window/TaskSnapshot.java
index a37bef8..53c64bd 100644
--- a/core/java/android/window/TaskSnapshot.java
+++ b/core/java/android/window/TaskSnapshot.java
@@ -77,6 +77,8 @@
     private final ColorSpace mColorSpace;
     private int mInternalReferences;
 
+    /** Keep in cache, doesn't need reference. */
+    public static final int REFERENCE_NONE = 0;
     /** This snapshot object is being broadcast. */
     public static final int REFERENCE_BROADCAST = 1;
     /** This snapshot object is in the cache. */
@@ -85,11 +87,16 @@
     public static final int REFERENCE_PERSIST = 1 << 2;
     /** This snapshot object is being used for content suggestion. */
     public static final int REFERENCE_CONTENT_SUGGESTION = 1 << 3;
+    /** This snapshot object will be passing to external process. Keep the snapshot reference after
+     * writeToParcel*/
+    public static final int REFERENCE_WRITE_TO_PARCEL = 1 << 4;
     @IntDef(flag = true, prefix = { "REFERENCE_" }, value = {
+            REFERENCE_NONE,
             REFERENCE_BROADCAST,
             REFERENCE_CACHE,
             REFERENCE_PERSIST,
-            REFERENCE_CONTENT_SUGGESTION
+            REFERENCE_CONTENT_SUGGESTION,
+            REFERENCE_WRITE_TO_PARCEL
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ReferenceFlags {}
@@ -309,6 +316,11 @@
         dest.writeBoolean(mIsTranslucent);
         dest.writeBoolean(mHasImeSurface);
         dest.writeInt(mUiMode);
+        synchronized (this) {
+            if ((mInternalReferences & REFERENCE_WRITE_TO_PARCEL) != 0) {
+                removeReference(REFERENCE_WRITE_TO_PARCEL);
+            }
+        }
     }
 
     @Override
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index a88a172..c800119 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -486,7 +486,7 @@
     }
 
     /**
-     * Sets to containers adjacent to each other. Containers below two visible adjacent roots will
+     * Sets two containers adjacent to each other. Containers below two visible adjacent roots will
      * be made invisible. This currently only applies to TaskFragment containers created by
      * organizer.
      * @param root1 the first root.
@@ -495,9 +495,64 @@
     @NonNull
     public WindowContainerTransaction setAdjacentRoots(
             @NonNull WindowContainerToken root1, @NonNull WindowContainerToken root2) {
-        mHierarchyOps.add(HierarchyOp.createForAdjacentRoots(
-                root1.asBinder(),
-                root2.asBinder()));
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            mHierarchyOps.add(HierarchyOp.createForAdjacentRoots(
+                    root1.asBinder(),
+                    root2.asBinder()));
+            return this;
+        }
+        return setAdjacentRootSet(root1, root2);
+    }
+
+    /**
+     * Sets multiple containers adjacent to each other. Containers below the visible adjacent roots
+     * will be made invisible. This currently only applies to Task containers created by organizer.
+     *
+     * To remove one container from the adjacent roots, one can call {@link #clearAdjacentRoots}
+     * with the target container.
+     * To remove all containers from the adjacent roots, one much call {@link #clearAdjacentRoots}
+     * on each container if there were more than two containers in the set.
+     *
+     * For non-Task TaskFragment, use {@link #setAdjacentTaskFragments} instead.
+     *
+     * @param roots the Tasks that should be adjacent to each other.
+     * @throws IllegalArgumentException if roots have size < 2.
+     * @hide // TODO(b/373709676) Rename to setAdjacentRoots and update CTS.
+     */
+    @NonNull
+    public WindowContainerTransaction setAdjacentRootSet(
+            @NonNull WindowContainerToken... roots) {
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            throw new IllegalArgumentException("allowMultipleAdjacentTaskFragments is not enabled."
+                    + " Use #setAdjacentRoots instead.");
+        }
+        if (roots.length < 2) {
+            throw new IllegalArgumentException("setAdjacentRootSet must have size >= 2");
+        }
+        final IBinder[] rootTokens = new IBinder[roots.length];
+        for (int i = 0; i < roots.length; i++) {
+            rootTokens[i] = roots[i].asBinder();
+        }
+        mHierarchyOps.add(
+                new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS)
+                        .setContainers(rootTokens)
+                        .build());
+        return this;
+    }
+
+    /**
+     * Clears container adjacent.
+     * If {@link #setAdjacentRootSet} is called with more than 2 roots, calling this will only
+     * remove the given root from the adjacent set. The rest of roots will stay adjacent to each
+     * other.
+     *
+     * @param root the root container to clear the adjacent roots for.
+     * @hide
+     */
+    @NonNull
+    public WindowContainerTransaction clearAdjacentRoots(
+            @NonNull WindowContainerToken root) {
+        mHierarchyOps.add(HierarchyOp.createForClearAdjacentRoots(root.asBinder()));
         return this;
     }
 
@@ -967,18 +1022,6 @@
     }
 
     /**
-     * Clears container adjacent.
-     * @param root the root container to clear the adjacent roots for.
-     * @hide
-     */
-    @NonNull
-    public WindowContainerTransaction clearAdjacentRoots(
-            @NonNull WindowContainerToken root) {
-        mHierarchyOps.add(HierarchyOp.createForClearAdjacentRoots(root.asBinder()));
-        return this;
-    }
-
-    /**
      * Sets/removes the reparent leaf task flag for this {@code windowContainer}.
      * When this is set, the server side will try to reparent the leaf task to task display area
      * if there is an existing activity in history during the activity launch. This operation only
@@ -1520,6 +1563,9 @@
         @Nullable
         private IBinder mContainer;
 
+        @Nullable
+        private IBinder[] mContainers;
+
         // If this is same as mContainer, then only change position, don't reparent.
         @Nullable
         private IBinder mReparent;
@@ -1704,6 +1750,7 @@
         public HierarchyOp(@NonNull HierarchyOp copy) {
             mType = copy.mType;
             mContainer = copy.mContainer;
+            mContainers = copy.mContainers;
             mBounds = copy.mBounds;
             mIncludingParents = copy.mIncludingParents;
             mReparent = copy.mReparent;
@@ -1729,6 +1776,7 @@
         protected HierarchyOp(Parcel in) {
             mType = in.readInt();
             mContainer = in.readStrongBinder();
+            mContainers = in.createBinderArray();
             mBounds = in.readTypedObject(Rect.CREATOR);
             mIncludingParents = in.readBoolean();
             mReparent = in.readStrongBinder();
@@ -1780,6 +1828,13 @@
         }
 
         @NonNull
+        public IBinder[] getContainers() {
+            return mContainers;
+        }
+
+        /** @deprecated b/373709676 replace with {@link #getContainers()}. */
+        @Deprecated
+        @NonNull
         public IBinder getAdjacentRoot() {
             return mReparent;
         }
@@ -1869,7 +1924,7 @@
                 case HIERARCHY_OP_TYPE_REORDER: return "reorder";
                 case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT: return "childrenTasksReparent";
                 case HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT: return "setLaunchRoot";
-                case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS: return "setAdjacentRoot";
+                case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS: return "setAdjacentRoots";
                 case HIERARCHY_OP_TYPE_LAUNCH_TASK: return "launchTask";
                 case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT: return "setAdjacentFlagRoot";
                 case HIERARCHY_OP_TYPE_SET_DISABLE_LAUNCH_ADJACENT:
@@ -1883,7 +1938,7 @@
                 case HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP: return "setAlwaysOnTop";
                 case HIERARCHY_OP_TYPE_REMOVE_TASK: return "removeTask";
                 case HIERARCHY_OP_TYPE_FINISH_ACTIVITY: return "finishActivity";
-                case HIERARCHY_OP_TYPE_CLEAR_ADJACENT_ROOTS: return "clearAdjacentRoot";
+                case HIERARCHY_OP_TYPE_CLEAR_ADJACENT_ROOTS: return "clearAdjacentRoots";
                 case HIERARCHY_OP_TYPE_SET_REPARENT_LEAF_TASK_IF_RELAUNCH:
                     return "setReparentLeafTaskIfRelaunch";
                 case HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION:
@@ -1923,8 +1978,18 @@
                     sb.append(mContainer).append(" to ").append(mToTop ? "top" : "bottom");
                     break;
                 case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS:
-                    sb.append("container=").append(mContainer)
-                            .append(" adjacentRoot=").append(mReparent);
+                    if (Flags.allowMultipleAdjacentTaskFragments()) {
+                        for (IBinder container : mContainers) {
+                            if (container == mContainers[0]) {
+                                sb.append("adjacentRoots=").append(container);
+                            } else {
+                                sb.append(", ").append(container);
+                            }
+                        }
+                    } else {
+                        sb.append("container=").append(mContainer)
+                                .append(" adjacentRoot=").append(mReparent);
+                    }
                     break;
                 case HIERARCHY_OP_TYPE_LAUNCH_TASK:
                     sb.append(mLaunchOptions);
@@ -1997,6 +2062,7 @@
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(mType);
             dest.writeStrongBinder(mContainer);
+            dest.writeBinderArray(mContainers);
             dest.writeTypedObject(mBounds, flags);
             dest.writeBoolean(mIncludingParents);
             dest.writeStrongBinder(mReparent);
@@ -2044,6 +2110,9 @@
             private IBinder mContainer;
 
             @Nullable
+            private IBinder[] mContainers;
+
+            @Nullable
             private IBinder mReparent;
 
             @Nullable
@@ -2104,6 +2173,11 @@
                 return this;
             }
 
+            Builder setContainers(@Nullable IBinder[] containers) {
+                mContainers = containers;
+                return this;
+            }
+
             Builder setReparentContainer(@Nullable IBinder reparentContainer) {
                 mReparent = reparentContainer;
                 return this;
@@ -2209,6 +2283,7 @@
             HierarchyOp build() {
                 final HierarchyOp hierarchyOp = new HierarchyOp(mType);
                 hierarchyOp.mContainer = mContainer;
+                hierarchyOp.mContainers = mContainers;
                 hierarchyOp.mReparent = mReparent;
                 hierarchyOp.mWindowingModes = mWindowingModes != null
                         ? Arrays.copyOf(mWindowingModes, mWindowingModes.length)
diff --git a/core/java/android/window/WindowContext.java b/core/java/android/window/WindowContext.java
index 2b370b9..84a8b8f 100644
--- a/core/java/android/window/WindowContext.java
+++ b/core/java/android/window/WindowContext.java
@@ -32,6 +32,7 @@
 import android.view.WindowManager;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
 
 import java.lang.ref.Reference;
 
@@ -95,20 +96,20 @@
     }
 
     /**
-     * Updates this context to a new displayId.
+     * Moves this context to another display.
      * <p>
-     * Note that this doesn't re-parent previously attached windows (they should be removed and
-     * re-added manually after this is called). Resources associated with this context will have
-     * the correct value and configuration for the new display after this is called.
+     * Note that this re-parents all the previously attached windows. Resources associated with this
+     * context will have the correct value and configuration for the new display after this is
+     * called.
      */
-    @Override
-    public void updateDisplay(int displayId) {
-        if (displayId == getDisplayId()) {
-            return;
+    public void reparentToDisplay(int displayId) {
+        if (Flags.reparentWindowTokenApi()) {
+            if (displayId == getDisplayId()) {
+                return;
+            }
+            super.updateDisplay(displayId);
+            mController.reparentToDisplayArea(mType, displayId, mOptions);
         }
-        super.updateDisplay(displayId);
-        mController.detachIfNeeded();
-        mController.attachToDisplayArea(mType, displayId, mOptions);
     }
 
     @Override
diff --git a/core/java/android/window/WindowContextController.java b/core/java/android/window/WindowContextController.java
index c9ac245..1e2f454 100644
--- a/core/java/android/window/WindowContextController.java
+++ b/core/java/android/window/WindowContextController.java
@@ -158,6 +158,21 @@
         }
     }
 
+    /**
+     * Reparents the window context from the current attached display to another. {@code type} and
+     * {@code options} must be the same as the previous attach call, otherwise this will fail
+     * silently.
+     */
+    public void reparentToDisplayArea(
+            @WindowType int type, int displayId, @Nullable Bundle options) {
+        if (mAttachedToDisplayArea != AttachStatus.STATUS_ATTACHED) {
+            attachToDisplayArea(type, displayId, options);
+            return;
+        }
+        // No need to propagate type and options as this is already attached and they can't change.
+        getWindowTokenClientController().reparentToDisplayArea(mToken, displayId);
+    }
+
     /** Gets the {@link WindowTokenClientController}. */
     @VisibleForTesting
     @NonNull
diff --git a/core/java/android/window/WindowTokenClientController.java b/core/java/android/window/WindowTokenClientController.java
index fa34595..1ec05b6 100644
--- a/core/java/android/window/WindowTokenClientController.java
+++ b/core/java/android/window/WindowTokenClientController.java
@@ -197,6 +197,21 @@
         }
     }
 
+    /**
+     * Reparents a {@link WindowTokenClient} and its associated WindowContainer if there's one.
+     */
+    public void reparentToDisplayArea(@NonNull WindowTokenClient client, int displayId) {
+        try {
+            if (!getWindowManagerService().reparentWindowContextToDisplayArea(mAppThread, client,
+                    displayId)) {
+                Log.e(TAG,
+                        "Didn't succeed reparenting of " + client + " to displayId=" + displayId);
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     private void onWindowContextTokenAttached(@NonNull WindowTokenClient client,
             @NonNull WindowContextInfo info, boolean shouldReportConfigChange) {
         recordWindowContextToken(client);
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index a04071a..6caa20e2 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -414,6 +414,16 @@
 }
 
 flag {
+    name: "enable_desktop_recents_transitions_corners_bugfix"
+    namespace: "lse_desktop_experience"
+    description: "Enables rounded corners bugfix for Recents transitions."
+    bug: "383079261"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
     name: "enable_move_to_next_display_shortcut"
     namespace: "lse_desktop_experience"
     description: "Add new keyboard shortcut of moving a task into next display"
@@ -489,4 +499,22 @@
     namespace: "lse_desktop_experience"
     description: "Bugfixes / papercuts to bring Desktop Windowing to secondary displays."
     bug: "382023296"
+}
+
+flag {
+    name: "enable_top_visible_root_task_per_user_tracking"
+    namespace: "lse_desktop_experience"
+    description: "Enables tracking the top visible root tasks for a user."
+    bug: "381038076"
+    is_fixed_read_only: true
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
+    name: "enable_per_display_desktop_wallpaper_activity"
+    namespace: "lse_desktop_experience"
+    description: "Enables having a DesktopWallpaperActivity at a per-display level."
+    bug: "381935663"
 }
\ No newline at end of file
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 30f0c73..1c27515 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -455,6 +455,17 @@
 }
 
 flag {
+    name: "remove_defer_hiding_client"
+    namespace: "windowing_frontend"
+    description: "Remove mDeferHidingClient since everything is in shell-transition."
+    is_fixed_read_only: true
+    bug: "382485959"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
   name: "relative_insets"
   namespace: "windowing_frontend"
   description: "Support insets definition and calculation relative to task bounds."
diff --git a/core/java/com/android/internal/app/EventLogTags.logtags b/core/java/com/android/internal/app/EventLogTags.logtags
index d681a8d..a18a824 100644
--- a/core/java/com/android/internal/app/EventLogTags.logtags
+++ b/core/java/com/android/internal/app/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
 
 option java_package com.android.internal.app;
 
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index f01aa80..2cfc680 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -163,5 +163,4 @@
     void finishOperationForDevice(IBinder clientId, int code, int uid, String packageName,
             @nullable String attributionTag, int virtualDeviceId);
    List<AppOpsManager.PackageOps> getPackagesForOpsForDevice(in int[] ops, String persistentDeviceId);
-   oneway void noteOperationsInBatch(in Map batchedNoteOps);
 }
diff --git a/core/java/com/android/internal/app/NfcResolverActivity.java b/core/java/com/android/internal/app/NfcResolverActivity.java
index 78427fe..f15dbd6 100644
--- a/core/java/com/android/internal/app/NfcResolverActivity.java
+++ b/core/java/com/android/internal/app/NfcResolverActivity.java
@@ -34,13 +34,13 @@
     @Override
     @SuppressWarnings("MissingSuperCall")  // Called indirectly via `super_onCreate()`.
     protected void onCreate(Bundle savedInstanceState) {
-        if (!enableNfcMainline()) {
+        Intent intent = getIntent();
+        if (!enableNfcMainline() || intent.getExtras() == null) {
             super_onCreate(savedInstanceState);
             finish();
             return;
         }
 
-        Intent intent = getIntent();
         Intent target = intent.getParcelableExtra(Intent.EXTRA_INTENT, Intent.class);
         ArrayList<ResolveInfo> rList =
                 intent.getParcelableArrayListExtra(
diff --git a/core/java/com/android/internal/content/om/OverlayManagerImpl.java b/core/java/com/android/internal/content/om/OverlayManagerImpl.java
index fa5cf2a..5d4e6a0 100644
--- a/core/java/com/android/internal/content/om/OverlayManagerImpl.java
+++ b/core/java/com/android/internal/content/om/OverlayManagerImpl.java
@@ -36,6 +36,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.parsing.FrameworkParsingPackageUtils;
 import android.content.res.AssetManager;
+import android.content.res.Flags;
 import android.os.FabricatedOverlayInfo;
 import android.os.FabricatedOverlayInternal;
 import android.os.FabricatedOverlayInternalEntry;
@@ -235,17 +236,24 @@
         Preconditions.checkArgument(!entryList.isEmpty(), "overlay entries shouldn't be empty");
         final String overlayName = checkOverlayNameValid(overlayInternal.overlayName);
         checkPackageName(overlayInternal.packageName);
-        Preconditions.checkStringNotEmpty(overlayInternal.targetPackageName);
+        if (Flags.selfTargetingAndroidResourceFrro()) {
+            Preconditions.checkStringNotEmpty(overlayInternal.targetPackageName);
+        } else {
+            checkPackageName(overlayInternal.targetPackageName);
+            Preconditions.checkStringNotEmpty(
+                    overlayInternal.targetOverlayable,
+                    "Target overlayable should be neither null nor empty string.");
+        }
 
         final ApplicationInfo applicationInfo = mContext.getApplicationInfo();
         String targetPackage = null;
-        if (TextUtils.equals(overlayInternal.targetPackageName, "android")) {
+        if (Flags.selfTargetingAndroidResourceFrro() && TextUtils.equals(
+                overlayInternal.targetPackageName, "android")) {
             targetPackage = AssetManager.FRAMEWORK_APK_PATH;
         } else {
             targetPackage = Preconditions.checkStringNotEmpty(
                     applicationInfo.getBaseCodePath());
         }
-
         final Path frroPath = mBasePath.resolve(overlayName + FRRO_EXTENSION);
         final Path idmapPath = mBasePath.resolve(overlayName + IDMAP_EXTENSION);
 
diff --git a/core/java/com/android/internal/inputmethod/InputMethodDebug.java b/core/java/com/android/internal/inputmethod/InputMethodDebug.java
index 2a5593f..4d5e67a 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodDebug.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodDebug.java
@@ -299,6 +299,12 @@
                 return "SHOW_SOFT_INPUT_IMM_DEPRECATION";
             case SoftInputShowHideReason.CONTROL_WINDOW_INSETS_ANIMATION:
                 return "CONTROL_WINDOW_INSETS_ANIMATION";
+            case SoftInputShowHideReason.SHOW_INPUT_TARGET_CHANGED:
+                return "SHOW_INPUT_TARGET_CHANGED";
+            case SoftInputShowHideReason.HIDE_INPUT_TARGET_CHANGED:
+                return "HIDE_INPUT_TARGET_CHANGED";
+            case SoftInputShowHideReason.HIDE_WINDOW_LOST_FOCUS:
+                return "HIDE_WINDOW_LOST_FOCUS";
             default:
                 return "Unknown=" + reason;
         }
diff --git a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
index 592ea9e..cf0580c 100644
--- a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
+++ b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
@@ -91,7 +91,7 @@
         SoftInputShowHideReason.CONTROL_WINDOW_INSETS_ANIMATION,
         SoftInputShowHideReason.SHOW_INPUT_TARGET_CHANGED,
         SoftInputShowHideReason.HIDE_INPUT_TARGET_CHANGED,
-        SoftInputShowHideReason.REASON_HIDE_WINDOW_LOST_FOCUS,
+        SoftInputShowHideReason.HIDE_WINDOW_LOST_FOCUS,
 })
 public @interface SoftInputShowHideReason {
     /** Default, undefined reason. */
@@ -340,18 +340,6 @@
     int HIDE_WINDOW_LEGACY_DIRECT = ImeProtoEnums.REASON_HIDE_WINDOW_LEGACY_DIRECT;
 
     /**
-     * Show soft input because the input target changed
-     * {@link com.android.server.wm.ImeInsetsSourceProvider#onInputTargetChanged}.
-     */
-    int SHOW_INPUT_TARGET_CHANGED = ImeProtoEnums.REASON_SHOW_INPUT_TARGET_CHANGED;
-
-    /**
-     * Hide soft input because the input target changed by
-     * {@link com.android.server.wm.ImeInsetsSourceProvider#onInputTargetChanged}.
-     */
-    int HIDE_INPUT_TARGET_CHANGED = ImeProtoEnums.REASON_HIDE_INPUT_TARGET_CHANGED;
-
-    /**
      * Show / Hide soft input by
      * {@link android.inputmethodservice.InputMethodService#resetStateForNewConfiguration}.
      */
@@ -420,6 +408,18 @@
      */
     int CONTROL_WINDOW_INSETS_ANIMATION = ImeProtoEnums.REASON_CONTROL_WINDOW_INSETS_ANIMATION;
 
+    /**
+     * Show soft input because the input target changed
+     * {@link com.android.server.wm.ImeInsetsSourceProvider#onInputTargetChanged}.
+     */
+    int SHOW_INPUT_TARGET_CHANGED = ImeProtoEnums.REASON_SHOW_INPUT_TARGET_CHANGED;
+
+    /**
+     * Hide soft input because the input target changed by
+     * {@link com.android.server.wm.ImeInsetsSourceProvider#onInputTargetChanged}.
+     */
+    int HIDE_INPUT_TARGET_CHANGED = ImeProtoEnums.REASON_HIDE_INPUT_TARGET_CHANGED;
+
     /** Hide soft input when the window lost focus. */
-    int REASON_HIDE_WINDOW_LOST_FOCUS = ImeProtoEnums.REASON_HIDE_WINDOW_LOST_FOCUS;
+    int HIDE_WINDOW_LOST_FOCUS = ImeProtoEnums.REASON_HIDE_WINDOW_LOST_FOCUS;
 }
diff --git a/core/java/com/android/internal/logging/EventLogTags.logtags b/core/java/com/android/internal/logging/EventLogTags.logtags
index 693bd16..db47797 100644
--- a/core/java/com/android/internal/logging/EventLogTags.logtags
+++ b/core/java/com/android/internal/logging/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
 
 option java_package com.android.internal.logging;
 
diff --git a/core/java/com/android/internal/view/ScrollCaptureInternal.java b/core/java/com/android/internal/view/ScrollCaptureInternal.java
index 72b5488..0ed0613 100644
--- a/core/java/com/android/internal/view/ScrollCaptureInternal.java
+++ b/core/java/com/android/internal/view/ScrollCaptureInternal.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.view;
 
+import static android.view.flags.Flags.scrollCaptureRelaxScrollViewCriteria;
+
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.Resources;
@@ -49,7 +51,7 @@
     public static final int TYPE_FIXED = 0;
 
     /**
-     * Slides a single child view using mScrollX/mScrollY.
+     * Moves the viewport across absolute positioned child views using the scrollY property.
      */
     public static final int TYPE_SCROLLING = 1;
 
@@ -63,7 +65,7 @@
     /**
      * Unknown scrollable view with no child views (or not a subclass of ViewGroup).
      */
-    private static final int TYPE_OPAQUE = 3;
+    public static final int TYPE_OPAQUE = 3;
 
     /**
      * Performs tests on the given View and determines:
@@ -73,7 +75,7 @@
      * This needs to be fast and not alloc memory. It's called on everything in the tree not marked
      * as excluded during scroll capture search.
      */
-    private static int detectScrollingType(View view) {
+    public static int detectScrollingType(View view) {
         // Confirm that it can scroll.
         if (!(view.canScrollVertically(DOWN) || view.canScrollVertically(UP))) {
             // Nothing to scroll here, move along.
@@ -95,25 +97,25 @@
         if (DEBUG_VERBOSE) {
             Log.v(TAG, "hint: is a subclass of ViewGroup");
         }
-
-        // ScrollViews accept only a single child.
-        if (((ViewGroup) view).getChildCount() > 1) {
-            if (DEBUG_VERBOSE) {
-                Log.v(TAG, "hint: scrollable with multiple children");
+        // Flag: Optionally allow ScrollView-like ViewGroups which have more than one child view.
+        if (!scrollCaptureRelaxScrollViewCriteria()) {
+            // ScrollViews accept only a single child.
+            if (((ViewGroup) view).getChildCount() > 1) {
+                if (DEBUG_VERBOSE) {
+                    Log.v(TAG, "hint: scrollable with multiple children");
+                }
+                return TYPE_RECYCLING;
             }
-            return TYPE_RECYCLING;
         }
         // At least one child view is required.
-        if (((ViewGroup) view).getChildCount() < 1) {
-            if (DEBUG_VERBOSE) {
-                Log.v(TAG, "scrollable with no children");
-            }
+        if (((ViewGroup) view).getChildCount() == 0) {
+            Log.w(TAG, "scrollable but no children!");
             return TYPE_OPAQUE;
         }
         if (DEBUG_VERBOSE) {
             Log.v(TAG, "hint: single child view");
         }
-        //Because recycling containers don't use scrollY, a non-zero value means Scroll view.
+        // Because recycling containers don't use scrollY, a non-zero value means Scroll view.
         if (view.getScrollY() != 0) {
             if (DEBUG_VERBOSE) {
                 Log.v(TAG, "hint: scrollY != 0");
@@ -132,7 +134,7 @@
             Log.v(TAG, "hint: cannot be scrolled up");
         }
 
-        // canScrollVertically(UP) == false, getScrollY() == 0, getChildCount() == 1.
+        // canScrollVertically(UP) == false, getScrollY() == 0, getChildCount() >= 1.
         // For Recycling containers, this should be a no-op (RecyclerView logs a warning)
         view.scrollTo(view.getScrollX(), 1);
 
diff --git a/core/java/com/android/internal/widget/CallLayout.java b/core/java/com/android/internal/widget/CallLayout.java
index c852575..3a7c75a 100644
--- a/core/java/com/android/internal/widget/CallLayout.java
+++ b/core/java/com/android/internal/widget/CallLayout.java
@@ -30,7 +30,6 @@
 import android.view.RemotableViewMethod;
 import android.widget.FrameLayout;
 import android.widget.RemoteViews;
-import android.widget.TextView;
 import android.widget.flags.Flags;
 
 import com.android.internal.R;
@@ -59,7 +58,6 @@
     private CachingIconView mConversationIconView;
     private CachingIconView mIcon;
     private CachingIconView mConversationIconBadgeBg;
-    private TextView mConversationText;
 
     public CallLayout(@NonNull Context context) {
         super(context);
@@ -83,7 +81,6 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         mPeopleHelper.init(getContext());
-        mConversationText = findViewById(R.id.conversation_text);
         mConversationIconView = findViewById(R.id.conversation_icon);
         mIcon = findViewById(R.id.icon);
         mConversationIconBadgeBg = findViewById(R.id.conversation_icon_badge_bg);
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index 4b90420..b3ab5d3 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -777,37 +777,40 @@
 
         }
 
-        int conversationAvatarSize;
-        int facepileAvatarSize;
-        int facePileBackgroundSize;
-        if (mIsCollapsed) {
-            conversationAvatarSize = mConversationAvatarSize;
-            facepileAvatarSize = mFacePileAvatarSize;
-            facePileBackgroundSize = facepileAvatarSize + 2 * mFacePileProtectionWidth;
-        } else {
-            conversationAvatarSize = mConversationAvatarSizeExpanded;
-            facepileAvatarSize = mFacePileAvatarSizeExpandedGroup;
-            facePileBackgroundSize = facepileAvatarSize + 2 * mFacePileProtectionWidthExpanded;
+        if (!notificationsRedesignTemplates()) {
+            // We no longer need to update the size based on expansion state.
+            int conversationAvatarSize;
+            int facepileAvatarSize;
+            int facePileBackgroundSize;
+            if (mIsCollapsed) {
+                conversationAvatarSize = mConversationAvatarSize;
+                facepileAvatarSize = mFacePileAvatarSize;
+                facePileBackgroundSize = facepileAvatarSize + 2 * mFacePileProtectionWidth;
+            } else {
+                conversationAvatarSize = mConversationAvatarSizeExpanded;
+                facepileAvatarSize = mFacePileAvatarSizeExpandedGroup;
+                facePileBackgroundSize = facepileAvatarSize + 2 * mFacePileProtectionWidthExpanded;
+            }
+            LayoutParams layoutParams = (LayoutParams) mConversationFacePile.getLayoutParams();
+            layoutParams.width = conversationAvatarSize;
+            layoutParams.height = conversationAvatarSize;
+            mConversationFacePile.setLayoutParams(layoutParams);
+
+            layoutParams = (LayoutParams) bottomView.getLayoutParams();
+            layoutParams.width = facepileAvatarSize;
+            layoutParams.height = facepileAvatarSize;
+            bottomView.setLayoutParams(layoutParams);
+
+            layoutParams = (LayoutParams) topView.getLayoutParams();
+            layoutParams.width = facepileAvatarSize;
+            layoutParams.height = facepileAvatarSize;
+            topView.setLayoutParams(layoutParams);
+
+            layoutParams = (LayoutParams) bottomBackground.getLayoutParams();
+            layoutParams.width = facePileBackgroundSize;
+            layoutParams.height = facePileBackgroundSize;
+            bottomBackground.setLayoutParams(layoutParams);
         }
-        LayoutParams layoutParams = (LayoutParams) mConversationFacePile.getLayoutParams();
-        layoutParams.width = conversationAvatarSize;
-        layoutParams.height = conversationAvatarSize;
-        mConversationFacePile.setLayoutParams(layoutParams);
-
-        layoutParams = (LayoutParams) bottomView.getLayoutParams();
-        layoutParams.width = facepileAvatarSize;
-        layoutParams.height = facepileAvatarSize;
-        bottomView.setLayoutParams(layoutParams);
-
-        layoutParams = (LayoutParams) topView.getLayoutParams();
-        layoutParams.width = facepileAvatarSize;
-        layoutParams.height = facepileAvatarSize;
-        topView.setLayoutParams(layoutParams);
-
-        layoutParams = (LayoutParams) bottomBackground.getLayoutParams();
-        layoutParams.width = facePileBackgroundSize;
-        layoutParams.height = facePileBackgroundSize;
-        bottomBackground.setLayoutParams(layoutParams);
     }
 
     /**
@@ -832,6 +835,11 @@
      * update the icon position and sizing
      */
     private void updateIconPositionAndSize() {
+        if (notificationsRedesignTemplates()) {
+            // Icon size is fixed in the redesign.
+            return;
+        }
+
         int badgeProtrusion;
         int conversationAvatarSize;
         if (mIsOneToOne || mIsCollapsed) {
@@ -864,6 +872,11 @@
     }
 
     private void updatePaddingsBasedOnContentAvailability() {
+        if (notificationsRedesignTemplates()) {
+            // group icons have the same size as 1:1 conversations
+            return;
+        }
+
         // groups have avatars that need more spacing
         mMessagingLinearLayout.setSpacing(
                 mIsOneToOne ? mMessageSpacingStandard : mMessageSpacingGroup);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 19c6f51..9bd5237 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1326,7 +1326,7 @@
         try {
             getLockSettings().registerStrongAuthTracker(strongAuthTracker.getStub());
         } catch (RemoteException e) {
-            throw new RuntimeException("Could not register StrongAuthTracker");
+            e.rethrowFromSystemServer();
         }
     }
 
diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java
index 4305ba7..169a9e8 100644
--- a/core/java/com/android/internal/widget/MessagingGroup.java
+++ b/core/java/com/android/internal/widget/MessagingGroup.java
@@ -81,7 +81,6 @@
     private MessagingLinearLayout mMessageContainer;
     ImageFloatingTextView mSenderView;
     private ImageView mAvatarView;
-    private View mAvatarContainer;
     private String mAvatarSymbol = "";
     private int mLayoutColor;
     private CharSequence mAvatarName = "";
@@ -717,6 +716,11 @@
      * @param isInConversation is this in a conversation
      */
     public void setIsInConversation(boolean isInConversation) {
+        if (Flags.notificationsRedesignTemplates()) {
+            // No alignment adjustments are necessary in the redesign, as the size of the icons
+            // in both conversations and old messaging notifications are the same.
+            return;
+        }
         if (mIsInConversation != isInConversation) {
             mIsInConversation = isInConversation;
             MarginLayoutParams layoutParams =
diff --git a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
index 1e9ba78..33f93fc 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
@@ -699,6 +699,7 @@
             }
             op.markNotDirty();
             op.apply(context);
+            context.incrementOpCount();
         }
     }
 
@@ -1000,6 +1001,16 @@
     private final float[] mScaleOutput = new float[2];
     private final float[] mTranslateOutput = new float[2];
     private int mRepaintNext = -1; // delay to next repaint -1 = don't 1 = asap
+    private int mLastOpCount;
+
+    /**
+     * This is the number of ops used to calculate the last frame.
+     *
+     * @return number of ops
+     */
+    public int getOpsPerFrame() {
+        return mLastOpCount;
+    }
 
     /**
      * Returns > 0 if it needs to repaint
@@ -1017,6 +1028,7 @@
      * @param theme the theme we want to use for this document.
      */
     public void paint(@NonNull RemoteContext context, int theme) {
+        context.getLastOpCount();
         context.getPaintContext().clearNeedsRepaint();
         context.loadFloat(RemoteContext.ID_DENSITY, context.getDensity());
         context.mMode = RemoteContext.ContextMode.UNSET;
@@ -1027,21 +1039,24 @@
         context.mRemoteComposeState = mRemoteComposeState;
         context.mRemoteComposeState.setContext(context);
 
+        // If we have a content sizing set, we are going to take the original document
+        // dimension into account and apply scale+translate according to the RootContentBehavior
+        // rules.
         if (mContentSizing == RootContentBehavior.SIZING_SCALE) {
             // we need to add canvas transforms ops here
             computeScale(context.mWidth, context.mHeight, mScaleOutput);
-            computeTranslate(
-                    context.mWidth,
-                    context.mHeight,
-                    mScaleOutput[0],
-                    mScaleOutput[1],
-                    mTranslateOutput);
+            float sw = mScaleOutput[0];
+            float sh = mScaleOutput[1];
+            computeTranslate(context.mWidth, context.mHeight, sw, sh, mTranslateOutput);
             context.mPaintContext.translate(mTranslateOutput[0], mTranslateOutput[1]);
-            context.mPaintContext.scale(mScaleOutput[0], mScaleOutput[1]);
+            context.mPaintContext.scale(sw, sh);
+        } else {
+            // If not, we set the document width and height to be the current context width and
+            // height.
+            setWidth((int) context.mWidth);
+            setHeight((int) context.mHeight);
         }
         mTimeVariables.updateTime(context);
-        context.loadFloat(RemoteContext.ID_WINDOW_WIDTH, context.mWidth);
-        context.loadFloat(RemoteContext.ID_WINDOW_HEIGHT, context.mHeight);
         mRepaintNext = context.updateOps();
         if (mRootLayoutComponent != null) {
             if (context.mWidth != mRootLayoutComponent.getWidth()
@@ -1051,11 +1066,11 @@
             if (mRootLayoutComponent.needsMeasure()) {
                 mRootLayoutComponent.layout(context);
             }
-            // TODO -- this should be specifically about applying animation, not paint
-            mRootLayoutComponent.paint(context.getPaintContext());
-            context.mPaintContext.reset();
-            // TODO -- should be able to remove this
-            mRootLayoutComponent.updateVariables(context);
+            if (mRootLayoutComponent.needsBoundsAnimation()) {
+                mRepaintNext = 1;
+                mRootLayoutComponent.clearNeedsBoundsAnimation();
+                mRootLayoutComponent.animatingBounds(context);
+            }
             if (DEBUG) {
                 String hierarchy = mRootLayoutComponent.displayHierarchy();
                 System.out.println(hierarchy);
@@ -1081,6 +1096,7 @@
                         op.markNotDirty();
                         ((VariableSupport) op).updateVariables(context);
                     }
+                    context.incrementOpCount();
                     op.apply(context);
                 }
             }
@@ -1093,6 +1109,38 @@
         if (DEBUG && mRootLayoutComponent != null) {
             System.out.println(mRootLayoutComponent.displayHierarchy());
         }
+        mLastOpCount = context.getLastOpCount();
+    }
+
+    /**
+     * Get an estimated number of operations executed in a paint
+     *
+     * @return number of operations
+     */
+    public int getNumberOfOps() {
+        int count = mOperations.size();
+
+        for (Operation mOperation : mOperations) {
+            if (mOperation instanceof Component) {
+                count += getChildOps((Component) mOperation);
+            }
+        }
+        return count;
+    }
+
+    private int getChildOps(@NonNull Component base) {
+        int count = base.mList.size();
+        for (Operation mOperation : base.mList) {
+
+            if (mOperation instanceof Component) {
+                int mult = 1;
+                if (mOperation instanceof LoopOperation) {
+                    mult = ((LoopOperation) mOperation).estimateIterations();
+                }
+                count += mult * getChildOps((Component) mOperation);
+            }
+        }
+        return count;
     }
 
     @NonNull
@@ -1116,6 +1164,9 @@
             if (mOperation instanceof Component) {
                 Component com = (Component) mOperation;
                 count += addChildren(com, map, buffer);
+            } else if (mOperation instanceof LoopOperation) {
+                LoopOperation com = (LoopOperation) mOperation;
+                count += addChildren(com, map, buffer);
             }
         }
 
@@ -1153,6 +1204,35 @@
             if (mOperation instanceof Component) {
                 count += addChildren((Component) mOperation, map, tmp);
             }
+            if (mOperation instanceof LoopOperation) {
+                count += addChildren((LoopOperation) mOperation, map, tmp);
+            }
+        }
+        return count;
+    }
+
+    private int addChildren(
+            @NonNull LoopOperation base,
+            @NonNull HashMap<String, int[]> map,
+            @NonNull WireBuffer tmp) {
+        int count = base.mList.size();
+        for (Operation mOperation : base.mList) {
+            Class<? extends Operation> c = mOperation.getClass();
+            int[] values;
+            if (map.containsKey(c.getSimpleName())) {
+                values = map.get(c.getSimpleName());
+            } else {
+                values = new int[2];
+                map.put(c.getSimpleName(), values);
+            }
+            values[0] += 1;
+            values[1] += sizeOfComponent(mOperation, tmp);
+            if (mOperation instanceof Component) {
+                count += addChildren((Component) mOperation, map, tmp);
+            }
+            if (mOperation instanceof LoopOperation) {
+                count += addChildren((LoopOperation) mOperation, map, tmp);
+            }
         }
         return count;
     }
@@ -1198,7 +1278,6 @@
      * @param ctl the call back to allow evaluation of shaders
      */
     public void checkShaders(RemoteContext context, ShaderControl ctl) {
-        int count = 0;
         for (Operation op : mOperations) {
             if (op instanceof TextData) {
                 op.apply(context);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
index c03f44b..b5587ce 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
@@ -40,6 +40,7 @@
  * <p>We also contain a PaintContext, so that any operation can draw as needed.
  */
 public abstract class RemoteContext {
+    private static final int MAX_OP_COUNT = 100_000; // Maximum cmds per frame
     protected @NonNull CoreDocument mDocument =
             new CoreDocument(); // todo: is this a valid way to initialize? bbade@
     public @NonNull RemoteComposeState mRemoteComposeState =
@@ -52,6 +53,7 @@
 
     int mDebug = 0;
 
+    private int mOpCount;
     private int mTheme = Theme.UNSPECIFIED;
 
     public float mWidth = 0f;
@@ -631,4 +633,23 @@
             float right,
             float bottom,
             int metadataId);
+
+    /** increments the count of operations executed in a pass */
+    public void incrementOpCount() {
+        mOpCount++;
+        if (mOpCount > MAX_OP_COUNT) {
+            throw new RuntimeException("Too many operations executed");
+        }
+    }
+
+    /**
+     * Get the last Op Count and clear the count.
+     *
+     * @return the number of ops executed.
+     */
+    public int getLastOpCount() {
+        int count = mOpCount;
+        mOpCount = 0;
+        return count;
+    }
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java b/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java
index cd7ebec..ea917db 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java
@@ -24,7 +24,7 @@
 
 /** This generates the standard system variables for time. */
 public class TimeVariables {
-    private static final float BUILD = 0.01f;
+    private static final float BUILD = 0.02f;
 
     /**
      * This class populates all time variables in the system
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
index dcf1d25..e05bdf2 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
@@ -106,6 +106,7 @@
         for (Operation op : mList) {
             if (op instanceof TextData) {
                 op.apply(context);
+                context.incrementOpCount();
             }
         }
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
index e95dfda..8a77dc3 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
@@ -66,6 +66,34 @@
 
     protected float mZIndex = 0f;
 
+    private boolean mNeedsBoundsAnimation = false;
+
+    /**
+     * Mark the component as needing a bounds animation pass
+     */
+    public void markNeedsBoundsAnimation() {
+        mNeedsBoundsAnimation = true;
+        if (mParent != null && !mParent.mNeedsBoundsAnimation) {
+            mParent.markNeedsBoundsAnimation();
+        }
+    }
+
+    /**
+     * Clear the bounds animation pass flag
+     */
+    public void clearNeedsBoundsAnimation() {
+        mNeedsBoundsAnimation = false;
+    }
+
+    /**
+     * True if needs a bounds animation
+     *
+     * @return true if needs a bounds animation pass
+     */
+    public boolean needsBoundsAnimation() {
+        return mNeedsBoundsAnimation;
+    }
+
     public float getZIndex() {
         return mZIndex;
     }
@@ -382,12 +410,40 @@
         } else {
             mVisibility = m.getVisibility();
         }
-        setWidth(m.getW());
-        setHeight(m.getH());
-        setLayoutPosition(m.getX(), m.getY());
+        if (mAnimateMeasure == null) {
+            setWidth(m.getW());
+            setHeight(m.getH());
+            setLayoutPosition(m.getX(), m.getY());
+            updateComponentValues(context);
+            clearNeedsBoundsAnimation();
+        } else {
+            mAnimateMeasure.apply(context);
+            updateComponentValues(context);
+            markNeedsBoundsAnimation();
+        }
         mFirstLayout = false;
     }
 
+    /**
+     * Animate the bounds of the component as needed
+     * @param context
+     */
+    public void animatingBounds(@NonNull RemoteContext context) {
+        if (mAnimateMeasure != null) {
+            mAnimateMeasure.apply(context);
+            updateComponentValues(context);
+            markNeedsBoundsAnimation();
+        } else {
+            clearNeedsBoundsAnimation();
+        }
+        for (Operation op : mList) {
+            if (op instanceof Measurable) {
+                Measurable m = (Measurable) op;
+                m.animatingBounds(context);
+            }
+        }
+    }
+
     @NonNull public float[] locationInWindow = new float[2];
 
     public boolean contains(float x, float y) {
@@ -698,9 +754,6 @@
     }
 
     public void paintingComponent(@NonNull PaintContext context) {
-        if (!mComponentValues.isEmpty()) {
-            updateComponentValues(context.getContext());
-        }
         if (mPreTranslate != null) {
             mPreTranslate.paint(context);
         }
@@ -718,8 +771,10 @@
             }
             if (op instanceof PaintOperation) {
                 ((PaintOperation) op).paint(context);
+                context.getContext().incrementOpCount();
             } else {
                 op.apply(context.getContext());
+                context.getContext().incrementOpCount();
             }
         }
         context.restore();
@@ -728,7 +783,7 @@
 
     public boolean applyAnimationAsNeeded(@NonNull PaintContext context) {
         if (context.isAnimationEnabled() && mAnimateMeasure != null) {
-            mAnimateMeasure.apply(context);
+            mAnimateMeasure.paint(context);
             context.needsRepaint();
             return true;
         }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
index e25392c..9103885 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
@@ -286,7 +286,9 @@
     @Override
     public void paintingComponent(@NonNull PaintContext context) {
         Component prev = context.getContext().mLastComponent;
-        context.getContext().mLastComponent = this;
+        RemoteContext remoteContext = context.getContext();
+
+        remoteContext.mLastComponent = this;
         context.save();
         context.translate(mX, mY);
         if (context.isVisualDebug()) {
@@ -329,6 +331,7 @@
                     child.updateVariables(context.getContext());
                     child.markNotDirty();
                 }
+                remoteContext.incrementOpCount();
                 child.paint(context);
             }
         } else {
@@ -337,6 +340,7 @@
                     child.updateVariables(context.getContext());
                     child.markNotDirty();
                 }
+                remoteContext.incrementOpCount();
                 child.paint(context);
             }
         }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java
index 505656e..9fc5da8 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java
@@ -57,6 +57,7 @@
         for (Operation op : mList) {
             if (op instanceof TextData) {
                 op.apply(context);
+                context.incrementOpCount();
             }
         }
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
index 1b85681..ab1e0ac 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
@@ -107,9 +107,11 @@
 
     @Override
     public void paint(@NonNull PaintContext context) {
+        RemoteContext remoteContext = context.getContext();
         if (mIndexVariableId == 0) {
             for (float i = mFromOut; i < mUntilOut; i += mStepOut) {
                 for (Operation op : mList) {
+                    remoteContext.incrementOpCount();
                     op.apply(context.getContext());
                 }
             }
@@ -120,6 +122,7 @@
                     if (op instanceof VariableSupport && op.isDirty()) {
                         ((VariableSupport) op).updateVariables(context.getContext());
                     }
+                    remoteContext.incrementOpCount();
                     op.apply(context.getContext());
                 }
             }
@@ -172,4 +175,16 @@
                 .field(DocumentedOperation.FLOAT, "step", "value step")
                 .field(DocumentedOperation.FLOAT, "until", "stops less than or equal");
     }
+
+    /**
+     * Calculate and estimate of the number of iterations
+     *
+     * @return number of loops or 10 if based on variables
+     */
+    public int estimateIterations() {
+        if (!(Float.isNaN(mUntil) || Float.isNaN(mFrom) || Float.isNaN(mStep))) {
+            return (int) (0.5f + (mUntil - mFrom) / mStep);
+        }
+        return 10; // this is a generic estmate if the values are variables;
+    }
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
index 11c0f3f..11fa7ee 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
@@ -137,8 +137,8 @@
             return;
         }
         context.mLastComponent = this;
-        mWidth = context.mWidth;
-        mHeight = context.mHeight;
+        setWidth(context.mWidth);
+        setHeight(context.mHeight);
 
         // TODO: reuse MeasurePass
         MeasurePass measurePass = new MeasurePass();
@@ -155,7 +155,9 @@
     @Override
     public void paint(@NonNull PaintContext context) {
         mNeedsRepaint = false;
-        context.getContext().mLastComponent = this;
+        RemoteContext remoteContext = context.getContext();
+        remoteContext.mLastComponent = this;
+
         context.save();
 
         if (mParent == null) { // root layout
@@ -165,6 +167,7 @@
         for (Operation op : mList) {
             if (op instanceof PaintOperation) {
                 ((PaintOperation) op).paint(context);
+                remoteContext.incrementOpCount();
             }
         }
 
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java
index 2af3c73..1de956b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java
@@ -19,6 +19,7 @@
 
 import com.android.internal.widget.remotecompose.core.Operation;
 import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
 import com.android.internal.widget.remotecompose.core.operations.layout.Component;
 import com.android.internal.widget.remotecompose.core.operations.layout.DecoratorComponent;
 import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure;
@@ -103,13 +104,18 @@
 
     @NonNull public PaintBundle paint = new PaintBundle();
 
-    public void apply(@NonNull PaintContext context) {
-        update(context.getContext().currentTime);
-
+    /**
+     * Apply the layout portion of the animation if any
+     *
+     * @param context
+     */
+    public void apply(@NonNull RemoteContext context) {
+        update(context.currentTime);
         mComponent.setX(getX());
         mComponent.setY(getY());
         mComponent.setWidth(getWidth());
         mComponent.setHeight(getHeight());
+        mComponent.updateVariables(context);
 
         float w = mComponent.getWidth();
         float h = mComponent.getHeight();
@@ -120,10 +126,17 @@
                 h -= pop.getTop() + pop.getBottom();
             }
             if (op instanceof DecoratorComponent) {
-                ((DecoratorComponent) op).layout(context.getContext(), mComponent, w, h);
+                ((DecoratorComponent) op).layout(context, mComponent, w, h);
             }
         }
+    }
 
+    /**
+     * Paint the transition animation for the component owned
+     *
+     * @param context
+     */
+    public void paint(@NonNull PaintContext context) {
         if (mOriginal.getVisibility() != mTarget.getVisibility()) {
             if (mTarget.getVisibility() == Component.Visibility.GONE) {
                 switch (mExitAnimation) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java
index fbf2784..a999874 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java
@@ -44,4 +44,11 @@
      * @return true if need to remeasured, false otherwise
      */
     boolean needsMeasure();
+
+    /**
+     * Animate bounds of the component
+     *
+     * @param context
+     */
+    void animatingBounds(RemoteContext context);
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java
index d2ba13f..a1609ac 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java
@@ -49,6 +49,7 @@
         super.apply(context);
         for (ModifierOperation op : mList) {
             op.apply(context);
+            context.incrementOpCount();
         }
     }
 
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 7dad293..6eb83f1 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
@@ -250,8 +250,23 @@
         mInner.clearLocalString("SYSTEM:" + name);
     }
 
+    /**
+     * This is the number of ops used to calculate the last frame.
+     *
+     * @return number of ops
+     */
+    public int getOpsPerFrame() {
+        return mInner.getDocument().mDocument.getOpsPerFrame();
+    }
+
     /** Id action callback interface */
     public interface IdActionCallbacks {
+        /**
+         * Callback for on action
+         *
+         * @param id the id of the action
+         * @param metadata the metadata of the action
+         */
         void onAction(int id, String metadata);
     }
 
diff --git a/core/java/org/chromium/arc/EventLogTags.logtags b/core/java/org/chromium/arc/EventLogTags.logtags
index 1b7160e..8102d6f 100644
--- a/core/java/org/chromium/arc/EventLogTags.logtags
+++ b/core/java/org/chromium/arc/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
 
 option java_package org.chromium.arc
 
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 8e3303a..027113a 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -92,7 +92,6 @@
         "android_view_VelocityTracker.cpp",
         "android_view_VerifiedKeyEvent.cpp",
         "android_view_VerifiedMotionEvent.cpp",
-        "com_android_internal_util_ArrayUtils.cpp",
         "com_android_internal_util_VirtualRefBasePtr.cpp",
         "core_jni_helpers.cpp",
         ":deviceproductinfoconstants_aidl",
@@ -264,6 +263,7 @@
                 "com_android_internal_os_ZygoteCommandBuffer.cpp",
                 "com_android_internal_os_ZygoteInit.cpp",
                 "com_android_internal_security_VerityUtils.cpp",
+                "com_android_internal_util_ArrayUtils.cpp",
                 "hwbinder/EphemeralStorage.cpp",
                 "fd_utils.cpp",
                 "android_hardware_input_InputWindowHandle.cpp",
diff --git a/core/jni/android_app_PropertyInvalidatedCache.cpp b/core/jni/android_app_PropertyInvalidatedCache.cpp
index ead6666..12585d5 100644
--- a/core/jni/android_app_PropertyInvalidatedCache.cpp
+++ b/core/jni/android_app_PropertyInvalidatedCache.cpp
@@ -28,24 +28,77 @@
 #include "core_jni_helpers.h"
 #include "android_app_PropertyInvalidatedCache.h"
 
+namespace android::app::PropertyInvalidatedCache {
+
+// These provide run-time access to the sizing parameters.
+int NonceStore::getMaxNonce() const {
+    return kMaxNonce;
+}
+
+size_t NonceStore::getMaxByte() const {
+    return kMaxByte;
+}
+
+// Fetch a nonce, returning UNSET if the index is out of range.  This method specifically
+// does not throw or generate an error if the index is out of range; this allows the method
+// to be called in a CriticalNative JNI API.
+int64_t NonceStore::getNonce(int index) const {
+    if (index < 0 || index >= kMaxNonce) {
+        return UNSET;
+    } else {
+        return nonce()[index];
+    }
+}
+
+// Set a nonce and return true. Return false if the index is out of range.  This method
+// specifically does not throw or generate an error if the index is out of range; this
+// allows the method to be called in a CriticalNative JNI API.
+bool NonceStore::setNonce(int index, int64_t value) {
+    if (index < 0 || index >= kMaxNonce) {
+        return false;
+    } else {
+        nonce()[index] = value;
+        return true;
+    }
+}
+
+// Fetch just the byte-block hash
+int32_t NonceStore::getHash() const {
+    return mByteHash;
+}
+
+// Copy the byte block to the target and return the current hash.
+int32_t NonceStore::getByteBlock(block_t* block, size_t len) const {
+    memcpy(block, (void*) byteBlock(), std::min(kMaxByte, len));
+    return mByteHash;
+}
+
+// Set the byte block and the hash.
+void NonceStore::setByteBlock(int hash, const block_t* block, size_t len) {
+    memcpy((void*) byteBlock(), block, len = std::min(kMaxByte, len));
+    mByteHash = hash;
+}
+
+} // namespace android::app::PropertyInvalidatedCache;
+
 namespace {
 
 using namespace android::app::PropertyInvalidatedCache;
 
 // Convert a jlong to a nonce block.  This is a convenience function that should be inlined by
 // the compiler.
-inline SystemCacheNonce* sysCache(jlong ptr) {
-    return reinterpret_cast<SystemCacheNonce*>(ptr);
+inline NonceStore* nonceCache(jlong ptr) {
+    return reinterpret_cast<NonceStore*>(ptr);
 }
 
 // Return the number of nonces in the nonce block.
 jint getMaxNonce(JNIEnv*, jclass, jlong ptr) {
-    return sysCache(ptr)->getMaxNonce();
+    return nonceCache(ptr)->getMaxNonce();
 }
 
 // Return the number of string bytes in the nonce block.
 jint getMaxByte(JNIEnv*, jclass, jlong ptr) {
-    return sysCache(ptr)->getMaxByte();
+    return nonceCache(ptr)->getMaxByte();
 }
 
 // Set the byte block.  The first int is the hash to set and the second is the array to copy.
@@ -56,25 +109,25 @@
         jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "null byte block");
         return;
     }
-    sysCache(ptr)->setByteBlock(hash, value.get(), value.size());
+    nonceCache(ptr)->setByteBlock(hash, value.get(), value.size());
 }
 
 // Fetch the byte block.  If the incoming hash is the same as the local hash, the Java layer is
 // presumed to have an up-to-date copy of the byte block; do not copy byte array.  The local
 // hash is returned.
 jint getByteBlock(JNIEnv* env, jclass, jlong ptr, jint hash, jbyteArray val) {
-    if (sysCache(ptr)->getHash() == hash) {
+    if (nonceCache(ptr)->getHash() == hash) {
         return hash;
     }
     ScopedByteArrayRW value(env, val);
-    return sysCache(ptr)->getByteBlock(value.get(), value.size());
+    return nonceCache(ptr)->getByteBlock(value.get(), value.size());
 }
 
 // Fetch the byte block hash.
 //
 // This is a CriticalNative method and therefore does not get the JNIEnv or jclass parameters.
 jint getByteBlockHash(jlong ptr) {
-    return sysCache(ptr)->getHash();
+    return nonceCache(ptr)->getHash();
 }
 
 // Get a nonce value. So that this method can be CriticalNative, it returns 0 if the value is
@@ -83,7 +136,7 @@
 //
 // This method is @CriticalNative and does not take a JNIEnv* or jclass argument.
 jlong getNonce(jlong ptr, jint index) {
-    return sysCache(ptr)->getNonce(index);
+    return nonceCache(ptr)->getNonce(index);
 }
 
 // Set a nonce value. So that this method can be CriticalNative, it returns a boolean: false if
@@ -92,7 +145,7 @@
 //
 // This method is @CriticalNative and does not take a JNIEnv* or jclass argument.
 jboolean setNonce(jlong ptr, jint index, jlong value) {
-    return sysCache(ptr)->setNonce(index, value);
+    return nonceCache(ptr)->setNonce(index, value);
 }
 
 static const JNINativeMethod gMethods[] = {
diff --git a/core/jni/android_app_PropertyInvalidatedCache.h b/core/jni/android_app_PropertyInvalidatedCache.h
index eefa8fa..00aa281 100644
--- a/core/jni/android_app_PropertyInvalidatedCache.h
+++ b/core/jni/android_app_PropertyInvalidatedCache.h
@@ -18,10 +18,100 @@
 #include <memory.h>
 
 #include <atomic>
+#include <cstdint>
 
-namespace android {
-namespace app {
-namespace PropertyInvalidatedCache {
+namespace android::app::PropertyInvalidatedCache {
+
+/**
+ * A head of a CacheNonce object.  This contains all the fields that have a fixed size and
+ * location.  Fields with a variable location are found via offsets.  The offsets make this
+ * object position-independent, which is required because it is in shared memory and would be
+ * mapped into different virtual addresses for different processes.
+ */
+class NonceStore {
+  protected:
+    // A convenient typedef.  The jbyteArray element type is jbyte, which the compiler treats as
+    // signed char.
+    typedef signed char block_t;
+
+    // The nonce type.
+    typedef std::atomic<int64_t> nonce_t;
+
+    // Atomics should be safe to use across processes if they are lock free.
+    static_assert(nonce_t::is_always_lock_free == true);
+
+    // The value of an unset field.
+    static constexpr int UNSET = 0;
+
+    // The size of the nonce array.
+    const int32_t kMaxNonce;
+
+    // The size of the byte array.
+    const size_t kMaxByte;
+
+    // The offset to the nonce array.
+    const size_t mNonceOffset;
+
+    // The offset to the byte array.
+    const size_t mByteOffset;
+
+    // The byte block hash.  This is fixed and at a known offset, so leave it in the base class.
+    volatile std::atomic<int32_t> mByteHash;
+
+    // The constructor is protected!  It only makes sense when called from a subclass.
+    NonceStore(int kMaxNonce, size_t kMaxByte, volatile nonce_t* nonce, volatile block_t* block) :
+            kMaxNonce(kMaxNonce),
+            kMaxByte(kMaxByte),
+            mNonceOffset(offset(this, const_cast<nonce_t*>(nonce))),
+            mByteOffset(offset(this, const_cast<block_t*>(block))) {
+    }
+
+  public:
+
+    // These provide run-time access to the sizing parameters.
+    int getMaxNonce() const;
+    size_t getMaxByte() const;
+
+    // Fetch a nonce, returning UNSET if the index is out of range.  This method specifically
+    // does not throw or generate an error if the index is out of range; this allows the method
+    // to be called in a CriticalNative JNI API.
+    int64_t getNonce(int index) const;
+
+    // Set a nonce and return true. Return false if the index is out of range.  This method
+    // specifically does not throw or generate an error if the index is out of range; this
+    // allows the method to be called in a CriticalNative JNI API.
+    bool setNonce(int index, int64_t value);
+
+    // Fetch just the byte-block hash
+    int32_t getHash() const;
+
+    // Copy the byte block to the target and return the current hash.
+    int32_t getByteBlock(block_t* block, size_t len) const;
+
+    // Set the byte block and the hash.
+    void setByteBlock(int hash, const block_t* block, size_t len);
+
+  private:
+
+    // A convenience function to compute the offset between two unlike pointers.
+    static size_t offset(void const* base, void const* member) {
+        return reinterpret_cast<uintptr_t>(member) - reinterpret_cast<std::uintptr_t>(base);
+    }
+
+    // Return the address of the nonce array.
+    volatile nonce_t* nonce() const {
+        // The array is located at an offset from <this>.
+        return reinterpret_cast<nonce_t*>(
+            reinterpret_cast<std::uintptr_t>(this) + mNonceOffset);
+    }
+
+    // Return the address of the byte block array.
+    volatile block_t* byteBlock() const {
+        // The array is located at an offset from <this>.
+        return reinterpret_cast<block_t*>(
+            reinterpret_cast<std::uintptr_t>(this) + mByteOffset);
+    }
+};
 
 /**
  * A cache nonce block contains an array of std::atomic<int64_t> and an array of bytes.  The
@@ -36,111 +126,31 @@
  * The template is parameterized by the number of nonces it supports and the number of bytes in
  * the string block.
  */
-template<int maxNonce, size_t maxByte> class CacheNonce {
-
-    // The value of an unset field.
-    static const int UNSET = 0;
-
-    // A convenient typedef.  The jbyteArray element type is jbyte, which the compiler treats as
-    // signed char.
-    typedef signed char block_t;
+template<int maxNonce, size_t maxByte> class CacheNonce : public NonceStore {
 
     // The array of nonces
-    volatile std::atomic<int64_t> mNonce[maxNonce];
+    volatile nonce_t mNonce[maxNonce];
 
     // The byte array.  This is not atomic but it is guarded by the mByteHash.
     volatile block_t mByteBlock[maxByte];
 
-    // The hash that validates the byte block
-    volatile std::atomic<int32_t> mByteHash;
-
-    // Pad the class to a multiple of 8 bytes.
-    int32_t _pad;
-
   public:
-
-    // The expected size of this instance.  This is a compile-time constant and can be used in a
-    // static assertion.
-    static const int expectedSize =
-            maxNonce * sizeof(std::atomic<int64_t>)
-            + sizeof(std::atomic<int32_t>)
-            + maxByte * sizeof(block_t)
-            + sizeof(int32_t);
-
-    // These provide run-time access to the sizing parameters.
-    int getMaxNonce() const {
-        return maxNonce;
-    }
-
-    size_t getMaxByte() const {
-        return maxByte;
-    }
-
     // Construct and initialize the memory.
-    CacheNonce() {
+    CacheNonce() :
+            NonceStore(maxNonce, maxByte, &mNonce[0], &mByteBlock[0])
+    {
         for (int i = 0; i < maxNonce; i++) {
             mNonce[i] = UNSET;
         }
         mByteHash = UNSET;
         memset((void*) mByteBlock, UNSET, sizeof(mByteBlock));
     }
-
-    // Fetch a nonce, returning UNSET if the index is out of range.  This method specifically
-    // does not throw or generate an error if the index is out of range; this allows the method
-    // to be called in a CriticalNative JNI API.
-    int64_t getNonce(int index) const {
-        if (index < 0 || index >= maxNonce) {
-            return UNSET;
-        } else {
-            return mNonce[index];
-        }
-    }
-
-    // Set a nonce and return true. Return false if the index is out of range.  This method
-    // specifically does not throw or generate an error if the index is out of range; this
-    // allows the method to be called in a CriticalNative JNI API.
-    bool setNonce(int index, int64_t value) {
-        if (index < 0 || index >= maxNonce) {
-            return false;
-        } else {
-            mNonce[index] = value;
-            return true;
-        }
-    }
-
-    // Fetch just the byte-block hash
-    int32_t getHash() const {
-        return mByteHash;
-    }
-
-    // Copy the byte block to the target and return the current hash.
-    int32_t getByteBlock(block_t* block, size_t len) const {
-        memcpy(block, (void*) mByteBlock, std::min(maxByte, len));
-        return mByteHash;
-    }
-
-    // Set the byte block and the hash.
-    void setByteBlock(int hash, const block_t* block, size_t len) {
-        memcpy((void*) mByteBlock, block, len = std::min(maxByte, len));
-        mByteHash = hash;
-    }
 };
 
-/**
- * Sizing parameters for the system_server PropertyInvalidatedCache support.  A client can
- * retrieve the values through the accessors in CacheNonce instances.
- */
-static const int MAX_NONCE = 64;
-static const int BYTE_BLOCK_SIZE = 8192;
+// The CacheNonce for system server holds 64 nonces with a string block of 8192 bytes.  This is
+// more than enough for system_server PropertyInvalidatedCache support.  The configuration
+// values are not defined as visible constants.  Clients should use the accessors on the
+// SystemCacheNonce instance if they need the sizing parameters.
+typedef CacheNonce</* max nonce */ 64, /* byte block size */ 8192> SystemCacheNonce;
 
-// The CacheNonce for system server holds 64 nonces with a string block of 8192 bytes.
-typedef CacheNonce<MAX_NONCE, BYTE_BLOCK_SIZE> SystemCacheNonce;
-
-// The goal of this assertion is to ensure that the data structure is the same size across 32-bit
-// and 64-bit systems.
-static_assert(sizeof(SystemCacheNonce) == SystemCacheNonce::expectedSize,
-              "Unexpected SystemCacheNonce size");
-
-} // namespace PropertyInvalidatedCache
-} // namespace app
-} // namespace android
+} // namespace android.app.PropertyInvalidatedCache
diff --git a/core/jni/android_database_SQLiteRawStatement.cpp b/core/jni/android_database_SQLiteRawStatement.cpp
index 85a6bdf..5fa8083 100644
--- a/core/jni/android_database_SQLiteRawStatement.cpp
+++ b/core/jni/android_database_SQLiteRawStatement.cpp
@@ -70,12 +70,33 @@
     }
 }
 
+// If the last operation failed, throw an exception and return true.  Otherwise return false.
+static bool throwIfError(JNIEnv *env, jlong stmtPtr) {
+    switch (sqlite3_errcode(db(stmtPtr))) {
+        case SQLITE_OK:
+        case SQLITE_DONE:
+        case SQLITE_ROW: return false;
+    }
+    throw_sqlite3_exception(env, db(stmtPtr), nullptr);
+    return true;
+}
 
-// This throws a SQLiteBindOrColumnIndexOutOfRangeException if the column index is out
-// of bounds.  It returns true if an exception was thrown.
+// This throws a SQLiteBindOrColumnIndexOutOfRangeException if the column index is outside the
+// bounds of the row data set.  It throws SQLiteMisuseException if the statement's data column
+// count is zero; that generally occurs because the client has forgotten to call step() or the
+// client has stepped past the end of the query.  The function returns true if an exception was
+// thrown.
 static bool throwIfInvalidColumn(JNIEnv *env, jlong stmtPtr, jint col) {
-    if (col < 0 || col >= sqlite3_data_count(stmt(stmtPtr))) {
-        int count = sqlite3_data_count(stmt(stmtPtr));
+    int count = sqlite3_data_count(stmt(stmtPtr));
+    if (throwIfError(env, stmtPtr)) {
+        return true;
+    } else if (count == 0) {
+        // A count of zero indicates a misuse: the statement has never been step()'ed.
+        const char* message = "row has no data";
+        const char* errmsg = sqlite3_errstr(SQLITE_MISUSE);
+        throw_sqlite3_exception(env, SQLITE_MISUSE, errmsg, message);
+        return true;
+    } else if (col < 0 || col >= count) {
         std::string message = android::base::StringPrintf(
             "column index %d out of bounds [0,%d]", col, count - 1);
         char const * errmsg = sqlite3_errstr(SQLITE_RANGE);
@@ -86,15 +107,22 @@
     }
 }
 
-// If the last operation failed, throw an exception and return true.  Otherwise return false.
-static bool throwIfError(JNIEnv *env, jlong stmtPtr) {
-    switch (sqlite3_errcode(db(stmtPtr))) {
-        case SQLITE_OK:
-        case SQLITE_DONE:
-        case SQLITE_ROW: return false;
+// This throws a SQLiteBindOrColumnIndexOutOfRangeException if the column index is outside the
+// bounds of the result set.  (This is not the same as the data columns in a row).  The function
+// returns true if an exception was thrown.
+static bool throwIfInvalidResultColumn(JNIEnv *env, jlong stmtPtr, jint col) {
+    int count = sqlite3_column_count(stmt(stmtPtr));
+    if (throwIfError(env, stmtPtr)) {
+        return true;
+    } else if (col < 0 || col >= count) {
+        std::string message = android::base::StringPrintf(
+            "column index %d out of bounds [0,%d]", col, count - 1);
+        char const * errmsg = sqlite3_errstr(SQLITE_RANGE);
+        throw_sqlite3_exception(env, SQLITE_RANGE, errmsg, message.c_str());
+        return true;
+    } else {
+        return false;
     }
-    throw_sqlite3_exception(env, db(stmtPtr), nullptr);
-    return true;
 }
 
 static jint bindParameterCount(JNIEnv* env, jclass, jlong stmtPtr) {
@@ -226,7 +254,7 @@
 }
 
 static jstring columnName(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
-    if (throwIfInvalidColumn(env, stmtPtr, col)) {
+    if (throwIfInvalidResultColumn(env, stmtPtr, col)) {
         return nullptr;
     }
     const jchar* name = static_cast<const jchar*>(sqlite3_column_name16(stmt(stmtPtr), col));
diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp
index 805d5ad..cd39e6f 100644
--- a/core/jni/android_os_SELinux.cpp
+++ b/core/jni/android_os_SELinux.cpp
@@ -34,23 +34,27 @@
 
 namespace android {
 namespace {
-std::atomic<selabel_handle*> sehandle{nullptr};
+std::atomic<selabel_handle *> file_sehandle{nullptr};
 
-selabel_handle* GetSELabelHandle() {
-    selabel_handle* h = sehandle.load();
+selabel_handle *GetSELabelHandle_impl(selabel_handle *(*handle_func)(),
+                                      std::atomic<selabel_handle *> *handle_cache) {
+    selabel_handle *h = handle_cache->load();
     if (h != nullptr) {
         return h;
     }
 
-    h = selinux_android_file_context_handle();
+    h = handle_func();
     selabel_handle* expected = nullptr;
-    if (!sehandle.compare_exchange_strong(expected, h)) {
+    if (!handle_cache->compare_exchange_strong(expected, h)) {
         selabel_close(h);
-        return sehandle.load();
+        return handle_cache->load();
     }
     return h;
 }
 
+selabel_handle *GetSELabelFileBackendHandle() {
+    return GetSELabelHandle_impl(selinux_android_file_context_handle, &file_sehandle);
+}
 }
 
 struct SecurityContext_Delete {
@@ -106,7 +110,7 @@
         return NULL;
     }
 
-    auto* selabel_handle = GetSELabelHandle();
+    auto *selabel_handle = GetSELabelFileBackendHandle();
     if (selabel_handle == NULL) {
         ALOGE("fileSelabelLookup => Failed to get SEHandle");
         return NULL;
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 7ef7829..dc72539 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -589,32 +589,6 @@
     return pri;
 }
 
-jboolean android_os_Process_setSwappiness(JNIEnv *env, jobject clazz,
-                                          jint pid, jboolean is_increased)
-{
-    char text[64];
-
-    if (is_increased) {
-        strcpy(text, "/sys/fs/cgroup/memory/sw/tasks");
-    } else {
-        strcpy(text, "/sys/fs/cgroup/memory/tasks");
-    }
-
-    struct stat st;
-    if (stat(text, &st) || !S_ISREG(st.st_mode)) {
-        return false;
-    }
-
-    int fd = open(text, O_WRONLY | O_CLOEXEC);
-    if (fd >= 0) {
-        sprintf(text, "%" PRId32, pid);
-        write(fd, text, strlen(text));
-        close(fd);
-    }
-
-    return true;
-}
-
 void android_os_Process_setArgV0(JNIEnv* env, jobject clazz, jstring name)
 {
     if (name == NULL) {
@@ -1396,7 +1370,6 @@
         {"getProcessGroup", "(I)I", (void*)android_os_Process_getProcessGroup},
         {"createProcessGroup", "(II)I", (void*)android_os_Process_createProcessGroup},
         {"getExclusiveCores", "()[I", (void*)android_os_Process_getExclusiveCores},
-        {"setSwappiness", "(IZ)Z", (void*)android_os_Process_setSwappiness},
         {"setArgV0Native", "(Ljava/lang/String;)V", (void*)android_os_Process_setArgV0},
         {"setUid", "(I)I", (void*)android_os_Process_setUid},
         {"setGid", "(I)I", (void*)android_os_Process_setGid},
diff --git a/core/jni/com_android_internal_content_FileSystemUtils.cpp b/core/jni/com_android_internal_content_FileSystemUtils.cpp
index 76ead2a..48c92c8 100644
--- a/core/jni/com_android_internal_content_FileSystemUtils.cpp
+++ b/core/jni/com_android_internal_content_FileSystemUtils.cpp
@@ -21,8 +21,6 @@
 #include <android-base/file.h>
 #include <android-base/hex.h>
 #include <android-base/unique_fd.h>
-#include <bionic/macros.h>
-#include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
 #include <linux/fs.h>
@@ -48,8 +46,8 @@
         return false;
     }
 
-    start = align_up(start, blockSize);
-    end = align_down(end, blockSize);
+    start = __builtin_align_up(start, blockSize);
+    end = __builtin_align_down(end, blockSize);
 
     uint64_t alignedLength;
     if (__builtin_sub_overflow(end, start, &alignedLength)) {
@@ -67,7 +65,7 @@
     int result =
             fallocate(fd.get(), FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, start, alignedLength);
     if (result < 0) {
-        ALOGE("fallocate failed to punch hole, error:%d", errno);
+        ALOGE("fallocate failed to punch hole: %m");
         return false;
     }
 
@@ -78,7 +76,7 @@
                 const std::vector<Elf64_Phdr> &programHeaders) {
     struct stat64 beforePunch;
     if (int result = lstat64(filePath, &beforePunch); result != 0) {
-        ALOGE("lstat64 failed for filePath %s, error:%d", filePath, errno);
+        ALOGE("lstat64 failed for filePath %s: %m", filePath);
         return false;
     }
 
@@ -190,7 +188,7 @@
     IF_ALOGD() {
         struct stat64 afterPunch;
         if (int result = lstat64(filePath, &afterPunch); result != 0) {
-            ALOGD("lstat64 failed for filePath %s, error:%d", filePath, errno);
+            ALOGD("lstat64 failed for filePath %s: %m", filePath);
             return false;
         }
         ALOGD("Size after punching holes st_blocks: %" PRIu64 ", st_blksize: %" PRIu64
@@ -269,7 +267,7 @@
 
     struct stat64 beforePunch;
     if (int result = lstat64(filePath, &beforePunch); result != 0) {
-        ALOGE("lstat64 failed for filePath %s, error:%d", filePath, errno);
+        ALOGE("lstat64 failed for filePath %s: %m", filePath);
         return false;
     }
 
@@ -348,7 +346,7 @@
     IF_ALOGD() {
         struct stat64 afterPunch;
         if (int result = lstat64(filePath, &afterPunch); result != 0) {
-            ALOGD("lstat64 failed for filePath %s, error:%d", filePath, errno);
+            ALOGD("lstat64 failed for filePath %s: %m", filePath);
             return false;
         }
         ALOGD("punchHolesInApk:: Size after punching holes st_blocks: %" PRIu64
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index aeaeeca..8c7b335 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -88,8 +88,8 @@
 #include "nativebridge/native_bridge.h"
 
 #if defined(__BIONIC__)
+#include <android/dlext_private.h>
 extern "C" void android_reset_stack_guards();
-extern "C" void android_set_16kb_appcompat_mode(bool enable_app_compat);
 #endif
 
 namespace {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6b05690..b0cc995 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4535,11 +4535,11 @@
     <permission android:name="android.permission.REQUEST_COMPANION_PROFILE_GLASSES"
         android:protectionLevel="normal" />
 
-    <!-- Allows application to request to be associated with a virtual display capable of streaming
+    <!-- Allows application to request to be associated with a virtual device capable of streaming
          Android applications
          ({@link android.companion.AssociationRequest#DEVICE_PROFILE_APP_STREAMING})
          by {@link android.companion.CompanionDeviceManager}.
-        <p>Not for use by third-party applications.
+         <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.REQUEST_COMPANION_PROFILE_APP_STREAMING"
                 android:protectionLevel="signature|privileged" />
@@ -4547,16 +4547,25 @@
     <!-- Allows application to request to stream content from an Android host to a nearby device
          ({@link android.companion.AssociationRequest#DEVICE_PROFILE_NEARBY_DEVICE_STREAMING})
          by {@link android.companion.CompanionDeviceManager}.
-        <p>Not for use by third-party applications.
+         <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.REQUEST_COMPANION_PROFILE_NEARBY_DEVICE_STREAMING"
         android:protectionLevel="signature|privileged" />
 
+    <!-- Allows application to request to stream content from an Android host to a nearby device
+         ({@link android.companion.AssociationRequest#DEVICE_PROFILE_SENSOR_DEVICE_STREAMING})
+         by {@link android.companion.CompanionDeviceManager}.
+         <p>Not for use by third-party applications.
+         @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ENABLE_LIMITED_VDM_ROLE)
+    -->
+    <permission android:name="android.permission.REQUEST_COMPANION_PROFILE_SENSOR_DEVICE_STREAMING"
+        android:protectionLevel="signature|privileged" />
+
     <!-- Allows application to request to be associated with a vehicle head unit capable of
          automotive projection
          ({@link android.companion.AssociationRequest#DEVICE_PROFILE_AUTOMOTIVE_PROJECTION})
          by {@link android.companion.CompanionDeviceManager}.
-        <p>Not for use by third-party applications.
+         <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.REQUEST_COMPANION_PROFILE_AUTOMOTIVE_PROJECTION"
                 android:protectionLevel="internal|role" />
@@ -4565,7 +4574,7 @@
          and/or data with other devices, such as notifications, photos and media
          ({@link android.companion.AssociationRequest#DEVICE_PROFILE_COMPUTER})
          by {@link android.companion.CompanionDeviceManager}.
-        <p>Not for use by third-party applications.
+         <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.REQUEST_COMPANION_PROFILE_COMPUTER"
                 android:protectionLevel="signature|privileged" />
@@ -6853,6 +6862,13 @@
     <permission android:name="android.permission.BATTERY_STATS"
         android:protectionLevel="signature|privileged|development" />
 
+    <!-- @SystemApi @hide Allows an application to collect high-precision PowerMonitor readings
+         <p>Protection level: signature|privileged|development
+         @FlaggedApi(android.permission.flags.Flags.FLAG_FINE_POWER_MONITOR_PERMISSION) -->
+    <permission android:name="android.permission.ACCESS_FINE_POWER_MONITORS"
+        android:protectionLevel="signature|privileged|development"
+        android:featureFlag="android.permission.flags.fine_power_monitor_permission" />
+
     <!--Allows an application to manage statscompanion.
     <p>Not for use by third-party applications.
          @hide -->
@@ -8792,6 +8808,17 @@
         android:protectionLevel="signature|privileged|vendorPrivileged"
         android:featureFlag="android.media.tv.flags.kids_mode_tvdb_sharing"/>
 
+    <!-- @SystemApi
+        @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled")
+        This permission is required to access the specific text classifier you need from the
+        TextClassificationManager.
+        <p>Protection level: signature|role
+    @hide
+    -->
+    <permission android:name="android.permission.ACCESS_TEXT_CLASSIFIER_BY_TYPE"
+        android:protectionLevel="signature|role"
+        android:featureFlag="android.permission.flags.text_classifier_choice_api_enabled"/>
+
     <!-- Attribution for Geofencing service. -->
     <attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
     <!-- Attribution for Country Detector. -->
diff --git a/core/res/res/color-watch-v36/btn_material_filled_background_color.xml b/core/res/res/color-watch-v36/btn_material_filled_background_color.xml
deleted file mode 100644
index 70aace4..0000000
--- a/core/res/res/color-watch-v36/btn_material_filled_background_color.xml
+++ /dev/null
@@ -1,22 +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.
-  -->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false"
-          android:alpha="?attr/disabledAlpha"
-          android:color="?attr/materialColorOnSurface" />
-    <item android:color="?attr/materialColorPrimary" />
-</selector>
\ No newline at end of file
diff --git a/core/res/res/color-watch-v36/btn_material_filled_content_color.xml b/core/res/res/color-watch-v36/btn_material_filled_content_color.xml
deleted file mode 100644
index 4cc8fe5..0000000
--- a/core/res/res/color-watch-v36/btn_material_filled_content_color.xml
+++ /dev/null
@@ -1,22 +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.
-  -->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false"
-          android:alpha="?attr/primaryContentAlpha"
-          android:color="?attr/materialColorOnSurface" />
-    <item android:color="?attr/materialColorOnPrimary" />
-</selector>
\ No newline at end of file
diff --git a/core/res/res/color-watch-v36/btn_material_filled_tonal_content_color.xml b/core/res/res/color-watch-v36/btn_material_filled_tonal_content_color.xml
deleted file mode 100644
index 59810356..0000000
--- a/core/res/res/color-watch-v36/btn_material_filled_tonal_content_color.xml
+++ /dev/null
@@ -1,22 +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.
-  -->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false"
-          android:alpha="?attr/primaryContentAlpha"
-          android:color="?attr/materialColorOnSurface" />
-    <item android:color="?attr/materialColorOnSurface" />
-</selector>
\ No newline at end of file
diff --git a/core/res/res/color-watch-v36/btn_material_outlined_background_color.xml b/core/res/res/color-watch-v36/btn_material_outlined_background_color.xml
deleted file mode 100644
index 665f47f..0000000
--- a/core/res/res/color-watch-v36/btn_material_outlined_background_color.xml
+++ /dev/null
@@ -1,22 +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.
-  -->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false"
-          android:alpha="?attr/disabledAlpha"
-          android:color="?attr/materialColorOnSurface" />
-    <item android:color="?attr/materialColorOutline" />
-</selector>
diff --git a/core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml b/core/res/res/color/btn_material_filled_background_color_watch.xml
similarity index 80%
copy from core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml
copy to core/res/res/color/btn_material_filled_background_color_watch.xml
index b2a25af..78547bc 100644
--- a/core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml
+++ b/core/res/res/color/btn_material_filled_background_color_watch.xml
@@ -16,7 +16,7 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false"
-          android:alpha="?attr/disabledAlpha"
-          android:color="?attr/materialColorOnSurface" />
-    <item android:color="?attr/materialColorSurfaceContainer" />
+          android:alpha="@dimen/disabled_alpha_wear_material3"
+          android:color="@color/materialColorOnSurface" />
+    <item android:color="@color/materialColorPrimary" />
 </selector>
\ No newline at end of file
diff --git a/core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml b/core/res/res/color/btn_material_filled_content_color_watch.xml
similarity index 79%
copy from core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml
copy to core/res/res/color/btn_material_filled_content_color_watch.xml
index b2a25af..3a4ec3c 100644
--- a/core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml
+++ b/core/res/res/color/btn_material_filled_content_color_watch.xml
@@ -16,7 +16,7 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false"
-          android:alpha="?attr/disabledAlpha"
-          android:color="?attr/materialColorOnSurface" />
-    <item android:color="?attr/materialColorSurfaceContainer" />
+          android:alpha="@dimen/primary_content_alpha_wear_material3"
+          android:color="@color/materialColorOnSurface" />
+    <item android:color="@color/materialColorOnPrimary" />
 </selector>
\ No newline at end of file
diff --git a/core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml b/core/res/res/color/btn_material_filled_tonal_background_color_watch.xml
similarity index 79%
copy from core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml
copy to core/res/res/color/btn_material_filled_tonal_background_color_watch.xml
index b2a25af..e9b7e4c 100644
--- a/core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml
+++ b/core/res/res/color/btn_material_filled_tonal_background_color_watch.xml
@@ -16,7 +16,7 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false"
-          android:alpha="?attr/disabledAlpha"
-          android:color="?attr/materialColorOnSurface" />
-    <item android:color="?attr/materialColorSurfaceContainer" />
+          android:alpha="@dimen/disabled_alpha_wear_material3"
+          android:color="@color/materialColorOnSurface" />
+    <item android:color="@color/materialColorSurfaceContainer" />
 </selector>
\ No newline at end of file
diff --git a/core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml b/core/res/res/color/btn_material_filled_tonal_content_color_watch.xml
similarity index 79%
copy from core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml
copy to core/res/res/color/btn_material_filled_tonal_content_color_watch.xml
index b2a25af..8b5deda 100644
--- a/core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml
+++ b/core/res/res/color/btn_material_filled_tonal_content_color_watch.xml
@@ -16,7 +16,7 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false"
-          android:alpha="?attr/disabledAlpha"
-          android:color="?attr/materialColorOnSurface" />
-    <item android:color="?attr/materialColorSurfaceContainer" />
+          android:alpha="@dimen/primary_content_alpha_wear_material3"
+          android:color="@color/materialColorOnSurface" />
+    <item android:color="@color/materialColorOnSurface" />
 </selector>
\ No newline at end of file
diff --git a/core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml b/core/res/res/color/btn_material_outlined_background_color_watch.xml
similarity index 80%
rename from core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml
rename to core/res/res/color/btn_material_outlined_background_color_watch.xml
index b2a25af..f9c9a3f 100644
--- a/core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml
+++ b/core/res/res/color/btn_material_outlined_background_color_watch.xml
@@ -16,7 +16,7 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false"
-          android:alpha="?attr/disabledAlpha"
-          android:color="?attr/materialColorOnSurface" />
-    <item android:color="?attr/materialColorSurfaceContainer" />
-</selector>
\ No newline at end of file
+          android:alpha="@dimen/disabled_alpha_wear_material3"
+          android:color="@color/materialColorOnSurface" />
+    <item android:color="@color/materialColorOutline" />
+</selector>
diff --git a/core/res/res/color/input_method_switch_on_item.xml b/core/res/res/color/input_method_switch_on_item.xml
index 49fe081..f38e0ac 100644
--- a/core/res/res/color/input_method_switch_on_item.xml
+++ b/core/res/res/color/input_method_switch_on_item.xml
@@ -16,6 +16,6 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_activated="true" android:color="?attr/materialColorOnSecondaryContainer" />
-    <item android:color="?attr/materialColorOnSurface" />
+    <item android:state_activated="true" android:color="@color/materialColorOnSecondaryContainer" />
+    <item android:color="@color/materialColorOnSurface" />
 </selector>
diff --git a/core/res/res/color/notification_expand_button_state_tint.xml b/core/res/res/color/notification_expand_button_state_tint.xml
index 5a8594f..3409a2c 100644
--- a/core/res/res/color/notification_expand_button_state_tint.xml
+++ b/core/res/res/color/notification_expand_button_state_tint.xml
@@ -16,9 +16,9 @@
 
 <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="?androidprv:attr/materialColorOnPrimaryFixed"
+    <item android:state_pressed="true" android:color="@androidprv:color/materialColorOnPrimaryFixed"
           android:alpha="0.15"/>
-    <item android:state_hovered="true" android:color="?androidprv:attr/materialColorOnPrimaryFixed"
+    <item android:state_hovered="true" android:color="@androidprv:color/materialColorOnPrimaryFixed"
           android:alpha="0.11"/>
     <item android:color="@color/transparent" />
 </selector>
\ No newline at end of file
diff --git a/core/res/res/color/system_on_surface_disabled.xml b/core/res/res/color/system_on_surface_disabled.xml
index aba87f5..039ab02 100644
--- a/core/res/res/color/system_on_surface_disabled.xml
+++ b/core/res/res/color/system_on_surface_disabled.xml
@@ -15,6 +15,6 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="?attr/materialColorOnSurface"
+    <item android:color="@color/materialColorOnSurface"
           android:alpha="?attr/disabledAlpha" />
 </selector>
diff --git a/core/res/res/color/system_outline_disabled.xml b/core/res/res/color/system_outline_disabled.xml
index 0a67ce3..b5a6b6b 100644
--- a/core/res/res/color/system_outline_disabled.xml
+++ b/core/res/res/color/system_outline_disabled.xml
@@ -15,6 +15,6 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="?attr/materialColorOutline"
+    <item android:color="@color/materialColorOutline"
           android:alpha="?attr/disabledAlpha" />
 </selector>
diff --git a/core/res/res/color/system_surface_disabled.xml b/core/res/res/color/system_surface_disabled.xml
index 2d7fe7d..1572272 100644
--- a/core/res/res/color/system_surface_disabled.xml
+++ b/core/res/res/color/system_surface_disabled.xml
@@ -15,6 +15,6 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="?attr/materialColorSurface"
+    <item android:color="@color/materialColorSurface"
           android:alpha="?attr/disabledAlpha" />
 </selector>
diff --git a/core/res/res/drawable-watch-v36/dialog_alert_button_positive.xml b/core/res/res/drawable-watch-v36/dialog_alert_button_positive.xml
deleted file mode 100644
index 01ab073..0000000
--- a/core/res/res/drawable-watch-v36/dialog_alert_button_positive.xml
+++ /dev/null
@@ -1,22 +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.
-  -->
-
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/dialog_alert_button_background_positive"/>
-    <item
-        android:drawable="@drawable/ic_check"
-        android:gravity="center" />
-</layer-list>
\ No newline at end of file
diff --git a/core/res/res/drawable-watch-v36/btn_background_material_filled_tonal.xml b/core/res/res/drawable/btn_background_material_filled_tonal_watch.xml
similarity index 96%
rename from core/res/res/drawable-watch-v36/btn_background_material_filled_tonal.xml
rename to core/res/res/drawable/btn_background_material_filled_tonal_watch.xml
index fbd6973..69c467b 100644
--- a/core/res/res/drawable-watch-v36/btn_background_material_filled_tonal.xml
+++ b/core/res/res/drawable/btn_background_material_filled_tonal_watch.xml
@@ -18,7 +18,7 @@
         android:color="?attr/colorControlHighlight">
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="@color/btn_material_filled_tonal_background_color"/>
+            <solid android:color="@color/btn_material_filled_tonal_background_color_watch"/>
             <corners android:radius="@dimen/config_wearMaterial3_buttonCornerRadius"/>
             <size
                 android:width="@dimen/btn_material_width"
diff --git a/core/res/res/drawable-watch-v36/btn_background_material_filled.xml b/core/res/res/drawable/btn_background_material_filled_watch.xml
similarity index 97%
rename from core/res/res/drawable-watch-v36/btn_background_material_filled.xml
rename to core/res/res/drawable/btn_background_material_filled_watch.xml
index 6e74f64..76ba847 100644
--- a/core/res/res/drawable-watch-v36/btn_background_material_filled.xml
+++ b/core/res/res/drawable/btn_background_material_filled_watch.xml
@@ -18,7 +18,7 @@
         android:color="?attr/colorControlHighlight">
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="@color/btn_material_filled_background_color"/>
+            <solid android:color="@color/btn_material_filled_background_color_watch"/>
             <corners android:radius="@dimen/config_wearMaterial3_buttonCornerRadius"/>
             <size
                 android:width="@dimen/btn_material_width"
diff --git a/core/res/res/drawable-watch-v36/btn_background_material_outlined.xml b/core/res/res/drawable/btn_background_material_outlined_watch.xml
similarity index 97%
rename from core/res/res/drawable-watch-v36/btn_background_material_outlined.xml
rename to core/res/res/drawable/btn_background_material_outlined_watch.xml
index 7bc4060..16190aa 100644
--- a/core/res/res/drawable-watch-v36/btn_background_material_outlined.xml
+++ b/core/res/res/drawable/btn_background_material_outlined_watch.xml
@@ -30,7 +30,7 @@
             <corners android:radius="@dimen/config_wearMaterial3_buttonCornerRadius"/>
             <stroke
                 android:width="1dp"
-                android:color="@color/btn_material_outlined_background_color" />
+                android:color="@color/btn_material_outlined_background_color_watch" />
             <size
                 android:width="@dimen/btn_material_width"
                 android:height="@dimen/btn_material_height" />
diff --git a/core/res/res/drawable-watch-v36/btn_background_material_text.xml b/core/res/res/drawable/btn_background_material_text_watch.xml
similarity index 100%
rename from core/res/res/drawable-watch-v36/btn_background_material_text.xml
rename to core/res/res/drawable/btn_background_material_text_watch.xml
diff --git a/core/res/res/drawable-watch-v36/dialog_alert_button_background_negative.xml b/core/res/res/drawable/dialog_alert_button_background_negative_watch.xml
similarity index 97%
rename from core/res/res/drawable-watch-v36/dialog_alert_button_background_negative.xml
rename to core/res/res/drawable/dialog_alert_button_background_negative_watch.xml
index 0314bbe..495fa4a 100644
--- a/core/res/res/drawable-watch-v36/dialog_alert_button_background_negative.xml
+++ b/core/res/res/drawable/dialog_alert_button_background_negative_watch.xml
@@ -17,7 +17,7 @@
 
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
-    <solid android:color="@color/btn_material_filled_tonal_background_color"/>
+    <solid android:color="@color/btn_material_filled_tonal_background_color_watch"/>
     <corners android:radius="@dimen/config_wearMaterial3_bottomDialogCornerRadius" />
     <size
         android:width="@dimen/dialog_btn_negative_width"
diff --git a/core/res/res/drawable-watch-v36/dialog_alert_button_background_positive.xml b/core/res/res/drawable/dialog_alert_button_background_positive_watch.xml
similarity index 97%
rename from core/res/res/drawable-watch-v36/dialog_alert_button_background_positive.xml
rename to core/res/res/drawable/dialog_alert_button_background_positive_watch.xml
index 92262fb..20a4c0b 100644
--- a/core/res/res/drawable-watch-v36/dialog_alert_button_background_positive.xml
+++ b/core/res/res/drawable/dialog_alert_button_background_positive_watch.xml
@@ -21,7 +21,7 @@
         android:pivotX="50%"
         android:pivotY="50%">
     <shape android:shape="rectangle">
-        <solid android:color="@color/btn_material_filled_background_color"/>
+        <solid android:color="@color/btn_material_filled_background_color_watch"/>
         <corners android:radius="200dp" />
         <size
             android:width="63dp"
diff --git a/core/res/res/drawable-watch-v36/dialog_alert_button_negative.xml b/core/res/res/drawable/dialog_alert_button_negative_watch.xml
similarity index 91%
rename from core/res/res/drawable-watch-v36/dialog_alert_button_negative.xml
rename to core/res/res/drawable/dialog_alert_button_negative_watch.xml
index c155ba1..1776962 100644
--- a/core/res/res/drawable-watch-v36/dialog_alert_button_negative.xml
+++ b/core/res/res/drawable/dialog_alert_button_negative_watch.xml
@@ -15,8 +15,8 @@
   -->
 
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/dialog_alert_button_background_negative"/>
+    <item android:drawable="@drawable/dialog_alert_button_background_negative_watch"/>
     <item
-        android:drawable="@drawable/ic_close"
+        android:drawable="@drawable/ic_close_watch"
         android:gravity="center" />
 </layer-list>
\ No newline at end of file
diff --git a/core/res/res/drawable-watch-v36/dialog_alert_button_negative.xml b/core/res/res/drawable/dialog_alert_button_positive_watch.xml
similarity index 91%
copy from core/res/res/drawable-watch-v36/dialog_alert_button_negative.xml
copy to core/res/res/drawable/dialog_alert_button_positive_watch.xml
index c155ba1..ab08e2a 100644
--- a/core/res/res/drawable-watch-v36/dialog_alert_button_negative.xml
+++ b/core/res/res/drawable/dialog_alert_button_positive_watch.xml
@@ -15,8 +15,8 @@
   -->
 
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/dialog_alert_button_background_negative"/>
+    <item android:drawable="@drawable/dialog_alert_button_background_positive_watch"/>
     <item
-        android:drawable="@drawable/ic_close"
+        android:drawable="@drawable/ic_check_watch"
         android:gravity="center" />
 </layer-list>
\ No newline at end of file
diff --git a/core/res/res/drawable/floating_popup_background.xml b/core/res/res/drawable/floating_popup_background.xml
index 99acedf..7200954 100644
--- a/core/res/res/drawable/floating_popup_background.xml
+++ b/core/res/res/drawable/floating_popup_background.xml
@@ -18,7 +18,7 @@
 <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="?androidprv:attr/materialColorSurfaceContainerHighest"/>
+    <solid android:color="@androidprv:color/materialColorSurfaceContainerHighest"/>
     <corners android:radius="?android:attr/dialogCornerRadius" />
 </shape>
 
diff --git a/core/res/res/drawable-watch-v36/ic_check.xml b/core/res/res/drawable/ic_check_watch.xml
similarity index 93%
rename from core/res/res/drawable-watch-v36/ic_check.xml
rename to core/res/res/drawable/ic_check_watch.xml
index 7b01e64..2fc161f 100644
--- a/core/res/res/drawable-watch-v36/ic_check.xml
+++ b/core/res/res/drawable/ic_check_watch.xml
@@ -19,7 +19,7 @@
         android:height="28dp"
         android:viewportWidth="960"
         android:viewportHeight="960"
-        android:tint="@color/btn_material_filled_content_color">
-    <path android:fillColor="@color/btn_material_filled_content_color"
+        android:tint="@color/btn_material_filled_content_color_watch">
+    <path android:fillColor="@color/btn_material_filled_content_color_watch"
           android:pathData="M382,597.87L716.7,263.17Q730.37,249.5 748.76,249.5Q767.15,249.5 780.83,263.17Q794.5,276.85 794.5,295.62Q794.5,314.39 780.83,328.07L414.07,695.59Q400.39,709.26 382,709.26Q363.61,709.26 349.93,695.59L178.41,524.07Q164.74,510.39 165.12,491.62Q165.5,472.85 179.17,459.17Q192.85,445.5 211.62,445.5Q230.39,445.5 244.07,459.17L382,597.87Z"/>
 </vector>
diff --git a/core/res/res/drawable-watch-v36/ic_close.xml b/core/res/res/drawable/ic_close_watch.xml
similarity index 97%
rename from core/res/res/drawable-watch-v36/ic_close.xml
rename to core/res/res/drawable/ic_close_watch.xml
index 1f3da36..55e7213 100644
--- a/core/res/res/drawable-watch-v36/ic_close.xml
+++ b/core/res/res/drawable/ic_close_watch.xml
@@ -19,7 +19,7 @@
         android:height="28dp"
         android:viewportWidth="960"
         android:viewportHeight="960"
-        android:tint="@color/btn_material_filled_tonal_content_color">
-    <path android:fillColor="@color/btn_material_filled_tonal_content_color"
+        android:tint="@color/btn_material_filled_tonal_content_color_watch">
+    <path android:fillColor="@color/btn_material_filled_tonal_content_color_watch"
           android:pathData="M480,543.65L287.83,735.83Q275.15,748.5 256,748.5Q236.85,748.5 224.17,735.83Q211.5,723.15 211.5,704Q211.5,684.85 224.17,672.17L416.35,480L224.17,287.83Q211.5,275.15 211.5,256Q211.5,236.85 224.17,224.17Q236.85,211.5 256,211.5Q275.15,211.5 287.83,224.17L480,416.35L672.17,224.17Q684.85,211.5 704,211.5Q723.15,211.5 735.83,224.17Q748.5,236.85 748.5,256Q748.5,275.15 735.83,287.83L543.65,480L735.83,672.17Q748.5,684.85 748.5,704Q748.5,723.15 735.83,735.83Q723.15,748.5 704,748.5Q684.85,748.5 672.17,735.83L480,543.65Z"/>
 </vector>
diff --git a/core/res/res/drawable/immersive_cling_bg.xml b/core/res/res/drawable/immersive_cling_bg.xml
index de29c32..b28a423 100644
--- a/core/res/res/drawable/immersive_cling_bg.xml
+++ b/core/res/res/drawable/immersive_cling_bg.xml
@@ -20,5 +20,5 @@
     <corners
         android:bottomLeftRadius="28dp"
         android:bottomRightRadius="28dp"/>
-    <solid android:color="?androidprv:attr/materialColorSurfaceContainer" />
+    <solid android:color="@androidprv:color/materialColorSurfaceContainer" />
 </shape>
diff --git a/core/res/res/drawable/input_method_switch_button.xml b/core/res/res/drawable/input_method_switch_button.xml
index 396d81e..1ee9b81 100644
--- a/core/res/res/drawable/input_method_switch_button.xml
+++ b/core/res/res/drawable/input_method_switch_button.xml
@@ -30,7 +30,7 @@
             <shape android:shape="rectangle">
                 <corners android:radius="28dp"/>
                 <solid android:color="@color/transparent"/>
-                <stroke android:color="?attr/materialColorPrimary"
+                <stroke android:color="@color/materialColorPrimary"
                     android:width="1dp"/>
                 <padding android:left="16dp"
                     android:top="8dp"
diff --git a/core/res/res/drawable/input_method_switch_item_background.xml b/core/res/res/drawable/input_method_switch_item_background.xml
index eb7a246..ce5b6f9 100644
--- a/core/res/res/drawable/input_method_switch_item_background.xml
+++ b/core/res/res/drawable/input_method_switch_item_background.xml
@@ -29,7 +29,7 @@
             <item android:state_activated="true">
                 <shape android:shape="rectangle">
                     <corners android:radius="28dp"/>
-                    <solid android:color="?attr/materialColorSecondaryContainer"/>
+                    <solid android:color="@color/materialColorSecondaryContainer"/>
                 </shape>
             </item>
         </selector>
diff --git a/core/res/res/drawable-watch-v36/progress_ring_wear_material3.xml b/core/res/res/drawable/progress_ring_watch.xml
similarity index 90%
rename from core/res/res/drawable-watch-v36/progress_ring_wear_material3.xml
rename to core/res/res/drawable/progress_ring_watch.xml
index 5c0e5f6..8250ee6 100644
--- a/core/res/res/drawable-watch-v36/progress_ring_wear_material3.xml
+++ b/core/res/res/drawable/progress_ring_watch.xml
@@ -27,7 +27,7 @@
                 android:innerRadiusRatio="@dimen/progressbar_inner_radius_ratio"
                 android:thickness="@dimen/progressbar_thickness"
                 android:useLevel="false">
-                <solid android:color="?attr/materialColorSurfaceContainer"/>
+                <solid android:color="@color/materialColorSurfaceContainer"/>
             </shape>
         </item>
         <item>
@@ -36,7 +36,7 @@
                 android:innerRadiusRatio="@dimen/progressbar_inner_radius_ratio"
                 android:thickness="@dimen/progressbar_thickness"
                 android:useLevel="true">
-                <solid android:color="?attr/materialColorPrimary"/>
+                <solid android:color="@color/materialColorPrimary"/>
             </shape>
         </item>
     </layer-list>
diff --git a/core/res/res/layout-watch-v36/alert_dialog_wear_material3.xml b/core/res/res/layout-watch-v36/alert_dialog_wear_material3.xml
deleted file mode 100644
index 8f75456..0000000
--- a/core/res/res/layout-watch-v36/alert_dialog_wear_material3.xml
+++ /dev/null
@@ -1,113 +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.
-  -->
-
-<!-- This layout is the AlertDialog template. It overrides the system layout with the same name.
-    Make sure to include all the existing id of the overridden alert_dialog_material.-->
-<com.android.internal.widget.WatchListDecorLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/parentPanel"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <ScrollView
-        android:id="@+id/scrollView"
-        android:fillViewport="true"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent">
-        <LinearLayout
-            android:orientation="vertical"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content">
-            <!-- Top Panel -->
-            <FrameLayout
-                android:paddingLeft="?dialogPreferredPadding"
-                android:paddingRight="?dialogPreferredPadding"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:id="@+id/topPanel"
-                android:minHeight="@dimen/dialog_list_padding_top_no_title">
-                <include android:id="@+id/title_template"
-                         android:layout_width="match_parent"
-                         android:layout_height="wrap_content"
-                         layout="@layout/alert_dialog_title_material"/>
-            </FrameLayout>
-
-            <!-- Content Panel -->
-            <FrameLayout android:id="@+id/contentPanel"
-                         android:layout_width="match_parent"
-                         android:layout_height="wrap_content"
-                         android:clipToPadding="false">
-                <TextView android:id="@+id/message"
-                          android:layout_width="match_parent"
-                          android:layout_height="wrap_content"
-                          android:gravity="center_horizontal|top"
-                          android:textAppearance="@style/TextAppearance.DeviceDefault.Body1"
-                          android:paddingStart="?dialogPreferredPadding"
-                          android:paddingEnd="?dialogPreferredPadding"
-                          android:paddingTop="8dip"
-                          android:paddingBottom="8dip"/>
-            </FrameLayout>
-
-            <!-- Custom Panel, to replace content panel if needed -->
-            <FrameLayout android:id="@+id/customPanel"
-                         android:layout_width="match_parent"
-                         android:layout_height="match_parent"
-                         android:minHeight="64dp">
-                <FrameLayout android:id="@+android:id/custom"
-                             android:layout_width="match_parent"
-                             android:layout_height="wrap_content" />
-            </FrameLayout>
-
-            <!-- Button Panel -->
-            <FrameLayout
-                android:id="@+id/buttonPanel"
-                android:minHeight="@dimen/dialog_list_padding_bottom_no_buttons"
-                android:layout_weight="1"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center">
-                <LinearLayout
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_gravity="bottom"
-                    android:orientation="vertical"
-                    android:paddingBottom="?dialogPreferredPadding"
-                    android:measureWithLargestChild="true">
-                    <Button android:id="@+id/button2"
-                            android:layout_width="wrap_content"
-                            android:layout_height="wrap_content"
-                            android:layout_gravity="center"
-                            android:gravity="center"
-                            android:layout_weight="1"
-                            style="@*android:style/Widget.DeviceDefault.Button.WearMaterial3"/>
-                    <Button android:id="@+id/button3"
-                            android:layout_width="wrap_content"
-                            android:layout_height="wrap_content"
-                            android:layout_gravity="center"
-                            android:gravity="center"
-                            android:layout_weight="1"
-                            style="?android:attr/buttonBarButtonStyle"/>
-                    <Button android:id="@+id/button1"
-                            android:layout_width="match_parent"
-                            android:layout_height="match_parent"
-                            android:layout_gravity="center"
-                            android:gravity="center"
-                            android:layout_weight="1"
-                            style="@*android:style/Widget.DeviceDefault.Button.Filled"/>
-                </LinearLayout>
-            </FrameLayout>
-        </LinearLayout>
-    </ScrollView>
-</com.android.internal.widget.WatchListDecorLayout>
diff --git a/core/res/res/layout-watch-v36/alert_dialog_icon_button_wear_material3.xml b/core/res/res/layout/alert_dialog_icon_button_watch.xml
similarity index 98%
rename from core/res/res/layout-watch-v36/alert_dialog_icon_button_wear_material3.xml
rename to core/res/res/layout/alert_dialog_icon_button_watch.xml
index 407ec7a..e5bc86c 100644
--- a/core/res/res/layout-watch-v36/alert_dialog_icon_button_wear_material3.xml
+++ b/core/res/res/layout/alert_dialog_icon_button_watch.xml
@@ -114,7 +114,7 @@
                         <ImageView
                             android:layout_width="match_parent"
                             android:layout_height="match_parent"
-                            android:src="@drawable/dialog_alert_button_positive"/>
+                            android:src="@drawable/dialog_alert_button_positive_watch"/>
                     </FrameLayout>
                 </LinearLayout>
             </FrameLayout>
diff --git a/core/res/res/layout/alert_dialog_title_watch.xml b/core/res/res/layout/alert_dialog_title_watch.xml
new file mode 100644
index 0000000..9c5148f
--- /dev/null
+++ b/core/res/res/layout/alert_dialog_title_watch.xml
@@ -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.
+  -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:gravity="top|center_horizontal">
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:adjustViewBounds="true">
+
+        <ImageView
+            android:id="@+id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginBottom="8dp"
+            android:maxHeight="32dp"
+            android:maxWidth="32dp"
+            android:src="@null" />
+    </FrameLayout>
+
+    <TextView
+        android:id="@+id/alertTitle"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/alertDialog_material_side_margin_title"
+        android:layout_marginEnd="@dimen/alertDialog_material_side_margin_title"
+        android:textAppearance="@style/TextAppearance.AlertDialog.Title"
+        android:gravity="center" />
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/alert_dialog_watch.xml b/core/res/res/layout/alert_dialog_watch.xml
new file mode 100644
index 0000000..cb81fc5
--- /dev/null
+++ b/core/res/res/layout/alert_dialog_watch.xml
@@ -0,0 +1,138 @@
+<!--
+  ~ 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.
+  -->
+
+<!-- This layout is the AlertDialog template. It overrides the system layout with the same name.
+    Make sure to include all the existing id of the overridden alert_dialog_material.-->
+<com.android.internal.widget.WatchListDecorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/parentPanel"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ScrollView
+        android:id="@+id/scrollView"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:fillViewport="true">
+
+        <requestFocus />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:layout_marginStart="@dimen/alertDialog_material_side_margin"
+            android:layout_marginEnd="@dimen/alertDialog_material_side_margin"
+            android:gravity="center_vertical">
+
+            <!-- Top Spacer -->
+            <View
+                android:layout_width="match_parent"
+                android:layout_height="@dimen/alertDialog_material_top_margin" />
+
+            <!-- Top Panel -->
+            <FrameLayout
+                android:id="@+id/topPanel"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:minHeight="@dimen/dialog_list_padding_top_no_title">
+
+                <include
+                    android:id="@+id/title_template"
+                    layout="@layout/alert_dialog_title_watch"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content" />
+            </FrameLayout>
+
+            <!-- Content Panel -->
+            <FrameLayout
+                android:id="@+id/contentPanel"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingTop="12dp">
+
+                <TextView
+                    android:id="@+id/message"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginStart="@dimen/alertDialog_material_side_margin_body"
+                    android:layout_marginEnd="@dimen/alertDialog_material_side_margin_body"
+                    android:textAppearance="@style/TextAppearance.AlertDialog.Body1"
+                    android:gravity="center_horizontal|top" />
+            </FrameLayout>
+
+            <!-- Custom Panel, to replace content panel if needed -->
+            <FrameLayout
+                android:id="@+id/customPanel"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:minHeight="64dp">
+
+                <FrameLayout
+                    android:id="@+android:id/custom"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content" />
+            </FrameLayout>
+
+            <!-- Button Panel -->
+            <FrameLayout
+                android:id="@+id/buttonPanel"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:minHeight="@dimen/dialog_list_padding_bottom_no_buttons">
+
+                <LinearLayout
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="16dp"
+                    android:layout_gravity="bottom"
+                    android:orientation="vertical">
+                    <!-- Positive Button -->
+                    <Button
+                        android:id="@+id/button1"
+                        style="@*android:style/Widget.DeviceDefault.Button.Filled"
+                        android:layout_width="match_parent"
+                        android:layout_height="match_parent"
+                        android:layout_gravity="center"
+                        android:gravity="center" />
+                    <!--Neutral Button -->
+                    <Button
+                        android:id="@+id/button3"
+                        style="@*android:style/Widget.DeviceDefault.Button.WearMaterial3"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="center"
+                        android:gravity="center" />
+                    <!-- Negative Button -->
+                    <Button
+                        android:id="@+id/button2"
+                        style="@*android:style/Widget.DeviceDefault.Button.WearMaterial3"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="4dp"
+                        android:layout_gravity="center"
+                        android:gravity="center" />
+                </LinearLayout>
+            </FrameLayout>
+
+            <!-- Bottom Spacer -->
+            <View
+                android:layout_width="match_parent"
+                android:layout_height="@dimen/alertDialog_material_bottom_margin" />
+
+        </LinearLayout>
+    </ScrollView>
+</com.android.internal.widget.WatchListDecorLayout>
diff --git a/core/res/res/layout/floating_popup_menu_button.xml b/core/res/res/layout/floating_popup_menu_button.xml
index 0b3861c..f6e6adf 100644
--- a/core/res/res/layout/floating_popup_menu_button.xml
+++ b/core/res/res/layout/floating_popup_menu_button.xml
@@ -54,7 +54,7 @@
         android:ellipsize="end"
         android:fontFamily="@*android:string/config_bodyFontFamily"
         android:textSize="@dimen/floating_toolbar_text_size"
-        android:textColor="?androidprv:attr/materialColorOnSurface"
+        android:textColor="@androidprv:color/materialColorOnSurface"
         android:background="@null"
         android:focusable="false"
         android:focusableInTouchMode="false"
diff --git a/core/res/res/layout/floating_popup_overflow_button.xml b/core/res/res/layout/floating_popup_overflow_button.xml
index a51836b..5fd774f 100644
--- a/core/res/res/layout/floating_popup_overflow_button.xml
+++ b/core/res/res/layout/floating_popup_overflow_button.xml
@@ -26,4 +26,4 @@
     android:paddingBottom="@dimen/floating_toolbar_menu_image_button_vertical_padding"
     android:scaleType="centerInside"
     android:background="?attr/actionBarItemBackground"
-    android:tint="?androidprv:attr/materialColorOnSurface" />
+    android:tint="@androidprv:color/materialColorOnSurface" />
diff --git a/core/res/res/layout/immersive_mode_cling.xml b/core/res/res/layout/immersive_mode_cling.xml
index 2cde9e6..4e869b7 100644
--- a/core/res/res/layout/immersive_mode_cling.xml
+++ b/core/res/res/layout/immersive_mode_cling.xml
@@ -42,7 +42,7 @@
             android:layout_marginTop="20dp"
             android:gravity="center_horizontal"
             android:text="@string/immersive_cling_title"
-            android:textColor="?androidprv:attr/materialColorOnSurface"
+            android:textColor="@androidprv:color/materialColorOnSurface"
             android:textSize="24sp"
             android:fontFamily="google-sans" />
 
@@ -54,7 +54,7 @@
             android:paddingTop="14dp"
             android:gravity="center_horizontal"
             android:text="@string/immersive_cling_description"
-            android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+            android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
             android:textSize="14sp"
             android:fontFamily="google-sans" />
 
@@ -72,7 +72,7 @@
             android:minWidth="48dp"
             android:minHeight="48dp"
             android:text="@string/immersive_cling_positive"
-            android:textColor="?androidprv:attr/materialColorOnPrimary"
+            android:textColor="@androidprv:color/materialColorOnPrimary"
             android:textAllCaps="false"
             android:textSize="14sp"
             android:textFontWeight="500"
diff --git a/core/res/res/layout/input_method_switch_item_divider.xml b/core/res/res/layout/input_method_switch_item_divider.xml
index 4f8c963..b56cfb7 100644
--- a/core/res/res/layout/input_method_switch_item_divider.xml
+++ b/core/res/res/layout/input_method_switch_item_divider.xml
@@ -26,7 +26,7 @@
     <View
         android:layout_width="match_parent"
         android:layout_height="1dp"
-        android:background="?attr/materialColorOutlineVariant"
+        android:background="@color/materialColorOutlineVariant"
         android:layout_marginStart="20dp"
         android:layout_marginEnd="24dp"
         android:importantForAccessibility="no"/>
diff --git a/core/res/res/layout/input_method_switch_item_header.xml b/core/res/res/layout/input_method_switch_item_header.xml
index f0080a6..05c73d0 100644
--- a/core/res/res/layout/input_method_switch_item_header.xml
+++ b/core/res/res/layout/input_method_switch_item_header.xml
@@ -33,6 +33,6 @@
         android:fontFamily="google-sans-text"
         android:textAppearance="?attr/textAppearance"
         android:accessibilityHeading="true"
-        android:textColor="?attr/materialColorPrimary"/>
+        android:textColor="@color/materialColorPrimary"/>
 
 </LinearLayout>
diff --git a/core/res/res/layout/input_method_switch_item_new.xml b/core/res/res/layout/input_method_switch_item_new.xml
index 7b241af..3688608 100644
--- a/core/res/res/layout/input_method_switch_item_new.xml
+++ b/core/res/res/layout/input_method_switch_item_new.xml
@@ -56,7 +56,7 @@
             android:marqueeRepeatLimit="1"
             android:singleLine="true"
             android:fontFamily="google-sans-text"
-            android:textColor="?attr/materialColorOnSurfaceVariant"
+            android:textColor="@color/materialColorOnSurfaceVariant"
             android:textAppearance="?attr/textAppearanceListItemSecondary"
             android:textAllCaps="true"
             android:visibility="gone"/>
diff --git a/core/res/res/layout/notification_2025_conversation_face_pile_layout.xml b/core/res/res/layout/notification_2025_conversation_face_pile_layout.xml
index b25adaa..68eafee 100644
--- a/core/res/res/layout/notification_2025_conversation_face_pile_layout.xml
+++ b/core/res/res/layout/notification_2025_conversation_face_pile_layout.xml
@@ -18,14 +18,14 @@
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/conversation_face_pile"
-    android:layout_width="@dimen/conversation_avatar_size"
-    android:layout_height="@dimen/conversation_avatar_size"
+    android:layout_width="@dimen/notification_2025_icon_circle_size"
+    android:layout_height="@dimen/notification_2025_icon_circle_size"
     android:forceHasOverlappingRendering="false"
     >
     <ImageView
         android:id="@+id/conversation_face_pile_top"
-        android:layout_width="@dimen/messaging_avatar_size"
-        android:layout_height="@dimen/messaging_avatar_size"
+        android:layout_width="@dimen/notification_2025_face_pile_avatar_size"
+        android:layout_height="@dimen/notification_2025_face_pile_avatar_size"
         android:scaleType="centerCrop"
         android:layout_gravity="end|top"
         android:background="@drawable/notification_icon_circle"
@@ -43,8 +43,8 @@
             />
         <ImageView
             android:id="@+id/conversation_face_pile_bottom"
-            android:layout_width="@dimen/messaging_avatar_size"
-            android:layout_height="@dimen/messaging_avatar_size"
+            android:layout_width="@dimen/notification_2025_face_pile_avatar_size"
+            android:layout_height="@dimen/notification_2025_face_pile_avatar_size"
             android:scaleType="centerCrop"
             android:layout_gravity="center"
             android:background="@drawable/notification_icon_circle"
diff --git a/core/res/res/layout/notification_2025_conversation_header.xml b/core/res/res/layout/notification_2025_conversation_header.xml
new file mode 100644
index 0000000..db79e79
--- /dev/null
+++ b/core/res/res/layout/notification_2025_conversation_header.xml
@@ -0,0 +1,171 @@
+<?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
+  -->
+
+<com.android.internal.widget.ConversationHeaderLinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/conversation_header"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:paddingTop="@dimen/notification_2025_margin"
+    >
+
+    <TextView
+        android:id="@+id/conversation_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
+        android:textSize="16sp"
+        android:singleLine="true"
+        android:layout_weight="1"
+        />
+
+    <TextView
+        android:id="@+id/app_name_divider"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Info"
+        android:layout_marginStart="@dimen/notification_conversation_header_separating_margin"
+        android:text="@string/notification_header_divider_symbol"
+        android:singleLine="true"
+        android:visibility="gone"
+        />
+
+    <!-- App Name -->
+    <com.android.internal.widget.ObservableTextView
+        android:id="@+id/app_name_text"
+        android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Info"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/notification_conversation_header_separating_margin"
+        android:singleLine="true"
+        android:visibility="gone"
+        />
+
+    <TextView
+        android:id="@+id/time_divider"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Info"
+        android:layout_marginStart="@dimen/notification_conversation_header_separating_margin"
+        android:text="@string/notification_header_divider_symbol"
+        android:singleLine="true"
+        android:visibility="gone"
+        />
+
+    <DateTimeView
+        android:id="@+id/time"
+        android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Time"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/notification_conversation_header_separating_margin"
+        android:showRelative="true"
+        android:singleLine="true"
+        android:visibility="gone"
+        />
+
+    <ViewStub
+        android:id="@+id/chronometer"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/notification_conversation_header_separating_margin"
+        android:layout="@layout/notification_template_part_chronometer"
+        android:visibility="gone"
+        />
+
+    <TextView
+        android:id="@+id/verification_divider"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Info"
+        android:layout_marginStart="@dimen/notification_conversation_header_separating_margin"
+        android:text="@string/notification_header_divider_symbol"
+        android:singleLine="true"
+        android:visibility="gone"
+        />
+
+    <ImageView
+        android:id="@+id/verification_icon"
+        android:layout_width="@dimen/notification_verification_icon_size"
+        android:layout_height="@dimen/notification_verification_icon_size"
+        android:layout_marginStart="@dimen/notification_conversation_header_separating_margin"
+        android:baseline="10dp"
+        android:scaleType="fitCenter"
+        android:src="@drawable/ic_notifications_alerted"
+        android:visibility="gone"
+        />
+
+    <TextView
+        android:id="@+id/verification_text"
+        android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Info"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/notification_conversation_header_separating_margin"
+        android:layout_weight="100"
+        android:showRelative="true"
+        android:singleLine="true"
+        android:visibility="gone"
+        />
+
+    <ImageButton
+        android:id="@+id/feedback"
+        android:layout_width="@dimen/notification_feedback_size"
+        android:layout_height="@dimen/notification_feedback_size"
+        android:layout_marginStart="@dimen/notification_header_separating_margin"
+        android:background="?android:selectableItemBackgroundBorderless"
+        android:contentDescription="@string/notification_feedback_indicator"
+        android:baseline="13dp"
+        android:scaleType="fitCenter"
+        android:src="@drawable/ic_feedback_indicator"
+        android:visibility="gone"
+        />
+
+    <ImageView
+        android:id="@+id/phishing_alert"
+        android:layout_width="@dimen/notification_phishing_alert_size"
+        android:layout_height="@dimen/notification_phishing_alert_size"
+        android:layout_marginStart="@dimen/notification_conversation_header_separating_margin"
+        android:baseline="10dp"
+        android:scaleType="fitCenter"
+        android:src="@drawable/ic_dialog_alert_material"
+        android:visibility="gone"
+        android:contentDescription="@string/notification_phishing_alert_content_description"
+        />
+
+    <ImageView
+        android:id="@+id/profile_badge"
+        android:layout_width="@dimen/notification_badge_size"
+        android:layout_height="@dimen/notification_badge_size"
+        android:layout_marginStart="@dimen/notification_conversation_header_separating_margin"
+        android:baseline="10dp"
+        android:scaleType="fitCenter"
+        android:visibility="gone"
+        android:contentDescription="@string/notification_work_profile_content_description"
+        />
+
+    <ImageView
+        android:id="@+id/alerted_icon"
+        android:layout_width="@dimen/notification_alerted_size"
+        android:layout_height="@dimen/notification_alerted_size"
+        android:layout_marginStart="@dimen/notification_conversation_header_separating_margin"
+        android:baseline="10dp"
+        android:contentDescription="@string/notification_alerted_content_description"
+        android:scaleType="fitCenter"
+        android:src="@drawable/ic_notifications_alerted"
+        android:visibility="gone"
+        />
+</com.android.internal.widget.ConversationHeaderLinearLayout>
diff --git a/core/res/res/layout/notification_2025_conversation_icon_container.xml b/core/res/res/layout/notification_2025_conversation_icon_container.xml
index 90befd9..7ec2450 100644
--- a/core/res/res/layout/notification_2025_conversation_icon_container.xml
+++ b/core/res/res/layout/notification_2025_conversation_icon_container.xml
@@ -18,32 +18,27 @@
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/conversation_icon_container"
-    android:layout_width="@dimen/conversation_content_start"
+    android:layout_width="@dimen/notification_2025_content_margin_start"
     android:layout_height="wrap_content"
     android:gravity="start|top"
     android:clipChildren="false"
     android:clipToPadding="false"
-    android:paddingTop="20dp"
-    android:paddingBottom="16dp"
     android:importantForAccessibility="no"
     >
 
     <FrameLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_margin="@dimen/notification_2025_margin"
         android:clipChildren="false"
         android:clipToPadding="false"
         android:layout_gravity="top|center_horizontal"
         >
 
-        <!-- Big icon: 48x48, 12dp padding top, 16dp padding sides -->
         <com.android.internal.widget.CachingIconView
             android:id="@+id/conversation_icon"
-            android:layout_width="@dimen/conversation_avatar_size"
-            android:layout_height="@dimen/conversation_avatar_size"
-            android:layout_marginLeft="@dimen/conversation_badge_protrusion"
-            android:layout_marginRight="@dimen/conversation_badge_protrusion"
-            android:layout_marginBottom="@dimen/conversation_badge_protrusion"
+            android:layout_width="@dimen/notification_2025_icon_circle_size"
+            android:layout_height="@dimen/notification_2025_icon_circle_size"
             android:background="@drawable/notification_icon_circle"
             android:clipToOutline="true"
             android:scaleType="centerCrop"
@@ -52,19 +47,25 @@
 
         <ViewStub
             android:layout="@layout/notification_2025_conversation_face_pile_layout"
-            android:layout_width="@dimen/conversation_avatar_size"
-            android:layout_height="@dimen/conversation_avatar_size"
-            android:layout_marginLeft="@dimen/conversation_badge_protrusion"
-            android:layout_marginRight="@dimen/conversation_badge_protrusion"
-            android:layout_marginBottom="@dimen/conversation_badge_protrusion"
+            android:layout_width="@dimen/notification_2025_icon_circle_size"
+            android:layout_height="@dimen/notification_2025_icon_circle_size"
             android:id="@+id/conversation_face_pile"
             />
 
+        <!-- The badge icon is visually aligned to the square containing the conversation icon,
+        but it has a border in the color of the background that is meant to delimit it from the
+        conversation icon. This border, although not visible due to the color, is technically
+        outside these bounds.
+        In order to align the badge properly to the bottom end of the square, we use a top/start
+        margin that is equal to (size of the conversation icon - size of the badge - size of the
+        border on one side).
+        -->
         <FrameLayout
             android:id="@+id/conversation_icon_badge"
-            android:layout_width="@dimen/conversation_icon_size_badged"
-            android:layout_height="@dimen/conversation_icon_size_badged"
-            android:layout_gravity="end|bottom"
+            android:layout_width="@dimen/notification_2025_conversation_icon_badge_size"
+            android:layout_height="@dimen/notification_2025_conversation_icon_badge_size"
+            android:layout_marginTop="@dimen/notification_2025_conversation_icon_badge_position"
+            android:layout_marginStart="@dimen/notification_2025_conversation_icon_badge_position"
             android:clipChildren="false"
             android:clipToPadding="false"
             >
@@ -83,7 +84,7 @@
                 android:id="@+id/icon"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
-                android:layout_margin="4dp"
+                android:layout_margin="@dimen/notification_2025_conversation_icon_badge_padding"
                 android:layout_gravity="center"
                 android:forceHasOverlappingRendering="false"
                 />
diff --git a/core/res/res/layout/notification_2025_messaging_group.xml b/core/res/res/layout/notification_2025_messaging_group.xml
index c1b491f..ecaf0b9 100644
--- a/core/res/res/layout/notification_2025_messaging_group.xml
+++ b/core/res/res/layout/notification_2025_messaging_group.xml
@@ -24,13 +24,13 @@
     android:orientation="horizontal" >
     <FrameLayout
         android:id="@+id/message_icon_container"
-        android:layout_width="@dimen/conversation_content_start"
+        android:layout_width="@dimen/notification_2025_content_margin_start"
         android:layout_height="wrap_content">
         <ImageView
             android:layout_gravity="top|center_horizontal"
             android:id="@+id/message_icon"
-            android:layout_width="@dimen/messaging_avatar_size"
-            android:layout_height="@dimen/messaging_avatar_size"
+            android:layout_width="@dimen/notification_2025_icon_circle_size"
+            android:layout_height="@dimen/notification_2025_icon_circle_size"
             android:background="@drawable/notification_icon_circle"
             android:clipToOutline="true"
             android:scaleType="centerCrop"
@@ -58,14 +58,14 @@
     </com.android.internal.widget.RemeasuringLinearLayout>
     <FrameLayout
         android:id="@+id/messaging_group_icon_container"
-        android:layout_width="@dimen/messaging_avatar_size"
-        android:layout_height="@dimen/messaging_avatar_size"
+        android:layout_width="@dimen/notification_2025_icon_circle_size"
+        android:layout_height="@dimen/notification_2025_icon_circle_size"
         android:layout_marginStart="12dp"
         android:visibility="gone"/>
     <FrameLayout
         android:id="@+id/messaging_group_sending_progress_container"
         android:layout_width="@dimen/messaging_group_sending_progress_size"
-        android:layout_height="@dimen/messaging_avatar_size"
+        android:layout_height="@dimen/notification_2025_icon_circle_size"
         android:layout_marginStart="12dp"
         android:layout_gravity="top"
         android:visibility="gone">
diff --git a/core/res/res/layout/notification_2025_template_collapsed_call.xml b/core/res/res/layout/notification_2025_template_collapsed_call.xml
index 614444d..c4bca11 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_call.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_call.xml
@@ -41,13 +41,13 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_weight="1"
-            android:layout_marginStart="@dimen/conversation_content_start"
+            android:layout_marginStart="@dimen/notification_2025_content_margin_start"
             android:orientation="vertical"
             android:paddingBottom="@dimen/notification_2025_margin"
             >
 
             <include
-                layout="@layout/notification_template_conversation_header"
+                layout="@layout/notification_2025_conversation_header"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 />
diff --git a/core/res/res/layout/notification_2025_template_conversation.xml b/core/res/res/layout/notification_2025_template_conversation.xml
index 0c4c7fb..f31f65e 100644
--- a/core/res/res/layout/notification_2025_template_conversation.xml
+++ b/core/res/res/layout/notification_2025_template_conversation.xml
@@ -60,11 +60,11 @@
                 <!-- Use layout_marginStart instead of paddingStart to work around strange
                      measurement behavior on lower display densities. -->
                 <include
-                    layout="@layout/notification_template_conversation_header"
+                    layout="@layout/notification_2025_conversation_header"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_marginBottom="2dp"
-                    android:layout_marginStart="@dimen/conversation_content_start"
+                    android:layout_marginStart="@dimen/notification_2025_content_margin_start"
                     />
 
                 <!-- Messages -->
@@ -86,7 +86,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="@dimen/notification_content_margin"
-            android:layout_marginStart="@dimen/conversation_content_start"
+            android:layout_marginStart="@dimen/notification_2025_content_margin_start"
             android:layout_marginEnd="@dimen/notification_content_margin_end" />
         <include layout="@layout/notification_material_action_list" />
     </com.android.internal.widget.RemeasuringLinearLayout>
diff --git a/core/res/res/layout/notification_2025_template_expanded_call.xml b/core/res/res/layout/notification_2025_template_expanded_call.xml
index 3ff71b7..2af0ec2 100644
--- a/core/res/res/layout/notification_2025_template_expanded_call.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_call.xml
@@ -49,13 +49,13 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_weight="1"
-                android:layout_marginStart="@dimen/conversation_content_start"
+                android:layout_marginStart="@dimen/notification_2025_content_margin_start"
                 android:orientation="vertical"
                 android:minHeight="68dp"
                 >
 
                 <include
-                    layout="@layout/notification_template_conversation_header"
+                    layout="@layout/notification_2025_conversation_header"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     />
@@ -97,7 +97,7 @@
             layout="@layout/notification_template_smart_reply_container"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginStart="@dimen/notification_content_margin_start"
+            android:layout_marginStart="@dimen/notification_2025_content_margin_start"
             android:layout_marginEnd="@dimen/notification_content_margin_end"
             android:layout_marginTop="@dimen/notification_content_margin"
             />
diff --git a/core/res/res/layout/notification_2025_template_expanded_messaging.xml b/core/res/res/layout/notification_2025_template_expanded_messaging.xml
index 5b58726..e3c2014 100644
--- a/core/res/res/layout/notification_2025_template_expanded_messaging.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_messaging.xml
@@ -33,7 +33,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="top"
-            android:layout_marginTop="@dimen/notification_content_margin_top"
+            android:layout_marginTop="@dimen/notification_2025_header_height"
             android:clipChildren="false"
             android:orientation="vertical">
 
diff --git a/core/res/res/layout/notification_2025_text.xml b/core/res/res/layout/notification_2025_text.xml
index 48b1083..474f6d2 100644
--- a/core/res/res/layout/notification_2025_text.xml
+++ b/core/res/res/layout/notification_2025_text.xml
@@ -21,6 +21,7 @@
     android:layout_height="@dimen/notification_text_height"
     android:layout_gravity="top"
     android:layout_marginTop="@dimen/notification_text_margin_top"
+    android:ellipsize="end"
     android:fadingEdge="horizontal"
     android:gravity="top"
     android:maxLines="1"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index edb926c..c02c13c 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -369,13 +369,13 @@
     <string name="permlab_statusBar" msgid="8798267849526214017">"deaktiveer of verander statusbalk"</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="permdesc_statusBarService" msgid="6652917399085712557">"Laat die app toe om die statusbalk te wees."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"vou statusbalk in of uit"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Laat die program toe om die statusbalk uit te vou of in te vou."</string>
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"wys kennisgewings as volskermaktiwiteite op \'n geslote skerm"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Laat die program toe om kennisgewings as volskermaktiwiteite op \'n geslote toestel te wys"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"installeer kortpaaie"</string>
-    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Stel \'n program in staat om Tuisskerm-kortpaaie by te voeg sonder gebruikerinmenging."</string>
+    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Stel \'n app in staat om Tuisskerm-kortpaaie by te voeg sonder gebruikerinmenging."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"deïnstalleer kortpaaie"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Laat die app toe om Tuisskerm-kortpaaie te verwyder sonder gebruikerinmenging."</string>
     <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"herlei uitgaande oproepe"</string>
@@ -387,17 +387,17 @@
     <string name="permlab_receiveMms" msgid="4000650116674380275">"ontvang teksboodskappe (MMS)"</string>
     <string name="permdesc_receiveMms" msgid="958102423732219710">"Laat die program toe om MMS-boodskappe te ontvang en te verwerk. Dit beteken dat die program boodskappe wat na jou toestel gestuur is kan monitor of uitvee, sonder dat jy dit gesien het."</string>
     <string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"Stuur seluitsendingboodskappe aan"</string>
-    <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"Laat die program toe om die seluitsendingmodule te bind om seluitsendingboodskappe aan te stuur wanneer hulle ontvang word. Seluitsendingwaarskuwings word in sommige liggings gelewer om jou oor noodsituasies te waarsku. Kwaadwillige programme kan met die werkverrigting of werking van jou toestel inmeng wanneer \'n noodseluitsending ontvang word."</string>
+    <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"Laat die app toe om aan die seluitsendingmodule te bind om seluitsendingboodskappe aan te stuur wanneer hulle ontvang word. Seluitsendingwaarskuwings word in sommige liggings gelewer om jou oor noodsituasies te waarsku. Kwaadwillige apps kan met die werkverrigting of werking van jou toestel inmeng wanneer \'n noodseluitsending ontvang word."</string>
     <string name="permlab_manageOngoingCalls" msgid="281244770664231782">"Bestuur voortgaande oproepe"</string>
     <string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"Stel \'n program in staat om besonderhede oor voortgaande oproepe op jou toestel te sien, en hierdie oproepe te beheer."</string>
     <string name="permlab_accessLastKnownCellId" msgid="7638226620825665130">"Kry toegang tot laaste bekende selidentiteit."</string>
     <string name="permdesc_accessLastKnownCellId" msgid="6664621339249308857">"Laat ’n app toe om toegang tot die laaste bekende selidentiteit te kry wat deur telefonie verskaf is"</string>
     <string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"lees seluitsending-boodskappe"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Laat die program toe om seluitsending-boodskappe te lees wat deur jou toestel ontvang word. Seluitsending-waarskuwings word in sommige plekke afgelewer om jou van noodsituasies te waarsku. Kwaadwillige programme mag inmeng met die prestasie of die werking van jou toestel wanneer \'n noodgeval se seluitsending ontvang word."</string>
+    <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Laat die app toe om seluitsending-boodskappe te lees wat deur jou toestel ontvang word. Seluitsending-waarskuwings word in sommige plekke afgelewer om jou van noodsituasies te waarsku. Kwaadwillige apps kan inmeng met die prestasie of die werking van jou toestel wanneer \'n noodgeval se seluitsending ontvang word."</string>
     <string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"lees ingetekende nuus"</string>
-    <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"Laat die program toe om details oor die tans gesinkroniseerde strome te kry."</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"Laat die app toe om details oor die tans gesinkroniseerde strome te kry."</string>
     <string name="permlab_sendSms" msgid="7757368721742014252">"SMS-boodskappe te stuur en te bekyk"</string>
-    <string name="permdesc_sendSms" msgid="6757089798435130769">"Laat die program toe om SMS-boodskappe te stuur. Dit kan tot onverwagse heffings lei. Kwaadwillige programme kan jou geld kos deur boodskappe sonder jou bevestiging te stuur."</string>
+    <string name="permdesc_sendSms" msgid="6757089798435130769">"Laat die app toe om SMS-boodskappe te stuur. Dit kan tot onverwagse heffings lei. Kwaadwillige apps kan jou geld kos deur boodskappe sonder jou bevestiging te stuur."</string>
     <string name="permlab_readSms" msgid="5164176626258800297">"lees jou teksboodskappe (SMS of MMS)"</string>
     <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"Hierdie program kan alle SMS\'e (teksboodskappe) wat op jou tablet geberg is, lees."</string>
     <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"Hierdie app kan alle SMS- (teks)-boodskappe lees wat op jou Android TV-toestel geberg is."</string>
@@ -411,24 +411,24 @@
     <string name="permlab_reorderTasks" msgid="7598562301992923804">"herrangskik lopende programme"</string>
     <string name="permdesc_reorderTasks" msgid="8796089937352344183">"Laat die program toe om take na die voorgrond of agtergrond te skuif. Die program kan dit moontlik sonder jou insette doen."</string>
     <string name="permlab_enableCarMode" msgid="893019409519325311">"aktiveer motormodus"</string>
-    <string name="permdesc_enableCarMode" msgid="56419168820473508">"Laat die program toe om die motormodus te aktiveer."</string>
+    <string name="permdesc_enableCarMode" msgid="56419168820473508">"Laat die app toe om die motormodus te aktiveer."</string>
     <string name="permlab_killBackgroundProcesses" msgid="6559320515561928348">"maak ander programme toe"</string>
     <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"Laat die app toe om agtergrondprosesse van ander apps te beëindig. Dit kan moontlik veroorsaak dat ander apps ophou werk."</string>
-    <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"Hierdie program kan bo-op ander programme verskyn"</string>
+    <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"Hierdie app kan bo-op ander apps verskyn"</string>
     <string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"Hierdie app kan bokant ander apps of ander dele van die skerm verskyn. Dit kan met normale appgebruik inmeng en die voorkoms van ander apps verander."</string>
     <string name="permlab_hideOverlayWindows" msgid="6382697828482271802">"versteek ander apps se oorleggers"</string>
     <string name="permdesc_hideOverlayWindows" msgid="5660242821651958225">"Hierdie app kan versoek dat die stelsel oorleggers wat oorspronklik van apps af kom, versteek sodat hulle nie bo-op hulle wys nie."</string>
     <string name="permlab_runInBackground" msgid="541863968571682785">"loop op die agtergrond"</string>
-    <string name="permdesc_runInBackground" msgid="4344539472115495141">"Hierdie program kan op die agtergrond loop. Dit kan die battery vinniger laat pap word."</string>
+    <string name="permdesc_runInBackground" msgid="4344539472115495141">"Hierdie app kan op die agtergrond loop. Dit kan die battery vinniger laat pap word."</string>
     <string name="permlab_useDataInBackground" msgid="783415807623038947">"gebruik data op die agtergrond"</string>
     <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Hierdie app kan data op die agtergrond gebruik. Dit kan die datagebruik vergroot."</string>
     <string name="permlab_schedule_exact_alarm" msgid="6683283918033029730">"Skeduleer handelinge met presiese tydsbesturing"</string>
     <string name="permdesc_schedule_exact_alarm" msgid="8198009212013211497">"Hierdie app kan werk skeduleer om op ’n gewenste tyd in die toekoms plaas te vind. Dit beteken ook dat die app kan werk wanneer die toestel nie aktief gebruik word nie."</string>
     <string name="permlab_use_exact_alarm" msgid="348045139777131552">"Skeduleer wekkers of geleentheidonthounotas"</string>
     <string name="permdesc_use_exact_alarm" msgid="7033761461886938912">"Hierdie app kan handelinge soos wekkers en onthounotas skeduleer om jou op ’n gewenste tyd in die toekoms in kennis te stel."</string>
-    <string name="permlab_persistentActivity" msgid="464970041740567970">"laat program altyd loop"</string>
-    <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"Laat die program toe om dele van ditself deurdringend in die geheue te hou. Dit kan geheue wat aan ander programme beskikbaar is, beperk, en die tablet stadiger maak."</string>
-    <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"Laat die program toe om dele daarvan in die geheue te laat voortbestaan. Dit kan geheue wat vir ander programme beskikbaar is, beperk en sodoende jou Android TV-toestel stadiger maak."</string>
+    <string name="permlab_persistentActivity" msgid="464970041740567970">"laat app altyd loop"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"Laat die app toe om dele van die app deurdringend in die geheue te hou. Dit kan geheue wat aan ander apps beskikbaar is, beperk, en die tablet stadiger maak."</string>
+    <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"Laat die app toe om dele daarvan in die geheue te laat voortbestaan. Dit kan geheue wat vir ander apps beskikbaar is, beperk en sodoende jou Android TV-toestel stadiger maak."</string>
     <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Laat die app toe om dele van die app deurdringend in die geheue te hou. Dit kan geheue wat aan ander apps beskikbaar is, beperk, en die foon stadiger maak."</string>
     <string name="permlab_foregroundService" msgid="1768855976818467491">"laat loop voorgronddiens"</string>
     <string name="permdesc_foregroundService" msgid="8720071450020922795">"Laat die program toe om van voorgronddienste gebruik te maak."</string>
@@ -465,8 +465,8 @@
     <string name="permlab_writeSettings" msgid="8057285063719277394">"verander stelsel-instellings"</string>
     <string name="permdesc_writeSettings" msgid="8293047411196067188">"Laat die program toe om die stelsel se instellingsdata te verander. Kwaadwillige programme kan dalk jou stelsel se opstelling korrupteer."</string>
     <string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"laat loop wanneer begin"</string>
-    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"Laat die program toe om homself te begin so gou as moontlik nadat die stelsel laai. Dit maak dat dit langer neem vir die tablet om te begin, en dit laat die foon toe om die tablet stadiger te maak omdat dit altyd loop."</string>
-    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Laat die program toe om self te begin sodra die stelsel klaar geselflaai het. Dit kan dalk daartoe lei dat die toestel langer neem om jou Android TV-toestel te begin, en laat die program toe om die hele toestel stadiger te maak deur altyd te loop."</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"Laat die app toe om self te begin sodra die stelsel geselflaai het. Dit maak dat dit langer neem vir die tablet om te begin, en dit laat die foon toe om die tablet stadiger te maak omdat dit altyd loop."</string>
+    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Laat die app toe om self te begin sodra die stelsel klaar geselflaai het. Dit kan dalk daartoe lei dat die toestel langer neem om jou Android TV-toestel te begin, en laat die app toe om die hele toestel stadiger te maak deur altyd te loop."</string>
     <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"Laat die program toe om homself te begin so gou as moontlik nadat die stelsel laai. Dit maak dat dit langer neem vir die foon om te begin, en dit laat die foon toe om die foon stadiger te maak omdat dit altyd loop."</string>
     <string name="permlab_broadcastSticky" msgid="4552241916400572230">"Stuur klewerige uitsending"</string>
     <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"Laat die app toe om vaste uitsendings te stuur, wat agterbly nadat die uitsending klaar is. Oormatige gebruik kan die tablet stadig of onstabiel maak deurdat dit te veel geheue gebruik."</string>
@@ -484,20 +484,20 @@
     <string name="permdesc_readCallLog" msgid="8964770895425873433">"Hierdie program kan jou oproepgeskiedenis lees."</string>
     <string name="permlab_writeCallLog" msgid="670292975137658895">"skryf oproeprekord"</string>
     <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Laat die app toe om jou tablet se oproeprekord, insluitende data oor inkomende en uitgaande oproepe, te verander. Kwaadwillige apps kan dit gebruik om jou oproeprekord uit te vee of te verander."</string>
-    <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Laat die program toe om jou Android TV-toestel se oproeprekord te wysig, insluitend data oor inkomende en uitgaande oproepe. Kwaadwillige programme kan dit gebruik om jou oproeprekord uit te vee of te wysig."</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Laat die program toe om jou foon se oproeprekord, insluitende data oor inkomende en uitgaande oproepe, te verander. Kwaadwillige programme kan dit gebruik om jou oproeprekord uit te vee of te verander."</string>
-    <string name="permlab_bodySensors" msgid="662918578601619569">"Kry toegang tot liggaamsensordata, soos polsslag, terwyl program gebruik word"</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Laat die app toe om jou Android TV-toestel se oproeprekord te wysig, insluitend data oor inkomende en uitgaande oproepe. Kwaadwillige apps kan dit gebruik om jou oproeprekord uit te vee of te wysig."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Laat die app toe om jou foon se oproeprekord, insluitende data oor inkomende en uitgaande oproepe, te verander. Kwaadwillige apps kan dit gebruik om jou oproeprekord uit te vee of te verander."</string>
+    <string name="permlab_bodySensors" msgid="662918578601619569">"Kry toegang tot liggaamsensordata, soos polsslag, terwyl app gebruik word"</string>
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Gee die app toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl die app  gebruik word."</string>
-    <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Kry toegang tot liggaamsensordata, soos polsslag, terwyl program op agtergrond is"</string>
-    <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Gee die program toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl dit op die agtergrond is."</string>
+    <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Kry toegang tot liggaamsensordata, soos polsslag, terwyl app op die agtergrond is"</string>
+    <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Gee die app toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl dit op die agtergrond is."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Lees kalendergebeurtenisse en -besonderhede"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Hierdie program kan alle kalendergebeurtenisse lees wat op jou tablet geberg is of jou kalenderdata stoor."</string>
-    <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Hierdie program kan alle kalendergeleenthede wat op jou Android TV-toestel geberg is, lees of jou kalenderdata stoor."</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Hierdie app kan alle kalendergebeurtenisse lees wat op jou tablet geberg is of jou kalenderdata stoor."</string>
+    <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Hierdie app kan alle kalendergeleenthede lees wat op jou Android TV-toestel geberg is of jou kalenderdata stoor."</string>
     <string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"Hierdie program kan alle kalendergebeurtenisse lees wat op jou foon geberg is of jou kalenderdata stoor."</string>
     <string name="permlab_writeCalendar" msgid="6422137308329578076">"voeg by of verander kalenderafsprake en stuur \'n e-pos aan gaste sonder eienaars se medewete"</string>
     <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"Hierdie program kan kalendergebeurtenisse op jou tablet byvoeg, verwyder of verander. Hierdie program kan boodskappe stuur wat lyk of dit van kalendereienaars af kom of gebeurtenisse verander sonder om hul eienaars in te lig."</string>
     <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"Hierdie program kan kalendergeleenthede op jou Android TV-toestel byvoeg, verwyder of verander. Hierdie program kan boodskappe stuur wat lyk of dit van kalendereienaars af kom of geleenthede verander sonder om hul eienaars in kennis te stel."</string>
-    <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Hierdie program kan kalendergebeurtenisse op jou foon byvoeg, verwyder of verander. Hierdie program kan boodskappe stuur wat lyk of dit van kalendereienaars af kom of gebeurtenisse verander sonder om hul eienaars in te lig."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Hierdie app kan kalendergebeurtenisse op jou foon byvoeg, verwyder of verander. Hierdie app kan boodskappe stuur wat lyk of dit van kalendereienaars af kom of gebeurtenisse verander sonder om hul eienaars in te lig."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"Kry toegang tot ekstra liggingverskaffer-bevele"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Gee die app toegang tot ekstra liggingverskaffer-bevele. Dit kan die app dalk toelaat om in te meng met die werking van die GPS of ander liggingbronne."</string>
     <string name="permlab_accessFineLocation" msgid="6426318438195622966">"kry net op die voorgrond toegang tot presiese ligging"</string>
@@ -515,7 +515,7 @@
     <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"bespeur skermskote van appvensters"</string>
     <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Hierdie app sal ingelig word as ’n skermskoot geneem word terwyl die app gebruik word."</string>
     <string name="permlab_sim_communication" msgid="176788115994050692">"stuur bevele na die SIM"</string>
-    <string name="permdesc_sim_communication" msgid="4179799296415957960">"Laat die program toe om bevele na die SIM te stuur. Dit is baie gevaarlik."</string>
+    <string name="permdesc_sim_communication" msgid="4179799296415957960">"Laat die app toe om bevele na die SIM te stuur. Dit is baie gevaarlik."</string>
     <string name="permlab_activityRecognition" msgid="1782303296053990884">"herken fisieke aktiwiteit"</string>
     <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Hierdie program kan jou fisieke aktiwiteit herken."</string>
     <string name="permlab_camera" msgid="6320282492904119413">"neem foto\'s en video\'s"</string>
@@ -534,19 +534,19 @@
     <string name="permlab_callPhone" msgid="1798582257194643320">"skakel foonnommers direk"</string>
     <string name="permdesc_callPhone" msgid="7892422187827695656">"Laat die app toe om foonnommers sonder jou insae te bel. Dit kan onvoorsiene heffings of oproepe tot gevolg hê. Neem kennis dat dit nie die app toelaat om noodnommers te bel nie. Kwaadwillige apps kan jou geld kos deur oproepe te maak sonder jou bevestiging of diensverskafferkodes te bel wat veroorsaak dat inkomende oproepe outomaties na ’n ander nommer aangestuur word."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"toegang tot kitsboodskapoproepdiens"</string>
-    <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Laat die program toe om die kitsboodskapdiens te gebruik om oproepe sonder jou ingryping te maak."</string>
+    <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Laat die app toe om die kitsboodskapdiens te gebruik om oproepe sonder jou ingryping te maak."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"lees foonstatus en identiteit"</string>
     <string name="permdesc_readPhoneState" msgid="7229063553502788058">"Laat die program toe om toegang tot die foonfunksies van die toestel te verkry. Hierdie toestemming laat die program toe om te bepaal wat die foonnommer en toestel-IDs is, of die oproep aan die gang is, en die afgeleë nommer wat deur \'n oproep verbind word."</string>
     <string name="permlab_readBasicPhoneState" msgid="3214853233263871347">"lees basiese telefoniestatus en -identiteit"</string>
     <string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"Gee die program toegang tot die toestel se basiese telefoniekenmerke."</string>
     <string name="permlab_manageOwnCalls" msgid="9033349060307561370">"roeteer oproepe deur die stelsel"</string>
-    <string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"Laat die program toe om sy oproepe deur die stelsel te stuur om die oproepervaring te verbeter."</string>
+    <string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"Laat die app toe om sy oproepe deur die stelsel te stuur om die oproepervaring te verbeter."</string>
     <string name="permlab_callCompanionApp" msgid="3654373653014126884">"sien en beheer oproepe deur die stelsel."</string>
     <string name="permdesc_callCompanionApp" msgid="8474168926184156261">"Laat die program toe om deurlopende oproepe op die toestel te sien en te beheer. Dit sluit inligting in soos oproepnommers vir oproepe en die toedrag van die oproepe."</string>
     <string name="permlab_exemptFromAudioRecordRestrictions" msgid="1164725468350759486">"vrygestel van beperkings op oudio-opnames"</string>
     <string name="permdesc_exemptFromAudioRecordRestrictions" msgid="2425117015896871976">"Stel die program vry van beperkings om oudio op te neem."</string>
     <string name="permlab_acceptHandover" msgid="2925523073573116523">"gaan voort met \'n oproep uit \'n ander app"</string>
-    <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Laat die program toe om \'n oproep voort te sit wat in \'n ander program begin is."</string>
+    <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Laat die app toe om \'n oproep voort te sit wat in \'n ander app begin is."</string>
     <string name="permlab_readPhoneNumbers" msgid="5668704794723365628">"lees foonnommers"</string>
     <string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"Laat die program toe om toegang tot die toestel se foonnommers te kry."</string>
     <string name="permlab_wakeLock" product="automotive" msgid="1904736682319375676">"hou motorskerm aan"</string>
@@ -558,7 +558,7 @@
     <string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"Laat die app toe om te keer dat jou Android TV-toestel slaap."</string>
     <string name="permdesc_wakeLock" product="default" msgid="3689523792074007163">"Laat die app toe om die foon te keer om te slaap."</string>
     <string name="permlab_transmitIr" msgid="8077196086358004010">"versend infrarooi"</string>
-    <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Laat die program toe om die tablet se infrarooisender te gebruik."</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Laat die app toe om die tablet se infrarooisender te gebruik."</string>
     <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"Laat die app toe om jou Android TV-toestel se infrarooisender te gebruik."</string>
     <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Laat die program toe om die foon se infrarooisender te gebruik."</string>
     <string name="permlab_setWallpaper" msgid="6959514622698794511">"stel muurpapier"</string>
@@ -566,25 +566,25 @@
     <string name="permlab_accessHiddenProfile" msgid="8607094418491556823">"Kry toegang tot versteekte profiele"</string>
     <string name="permdesc_accessHiddenProfile" msgid="1543153202481009676">"Laat die app toe om toegang tot versteekte profiele te kry."</string>
     <string name="permlab_setWallpaperHints" msgid="1153485176642032714">"verstel jou muurpapier se grootte"</string>
-    <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Laat die program toe om die stelsel se muurpapier se groottewenke te stel."</string>
+    <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Laat die app toe om die stelsel se muurpapier se groottewenke te stel."</string>
     <string name="permlab_setTimeZone" msgid="7922618798611542432">"stel tydsone"</string>
     <string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"Laat die app toe om die tablet se tydsone te verander."</string>
     <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"Laat die program toe om jou Android TV-toestel se tydsone te verander."</string>
-    <string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"Laat die program toe om die foon se tydsone te verander."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"Laat die app toe om die foon se tydsone te verander."</string>
     <string name="permlab_getAccounts" msgid="5304317160463582791">"soek rekeninge op die toestel"</string>
     <string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"Laat die app toe om die lys van rekeninge wat aan die tablet bekend is, te kry. Dit kan moontlik enige rekeninge wat geskep is deur apps wat jy geïnstalleer het, insluit."</string>
-    <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Laat die program toe om die lys rekeninge wat aan jou Android TV-toestel bekend is, te kry. Dit kan dalk rekeninge insluit wat geskep is deur programme wat jy geïnstalleer het."</string>
+    <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Laat die app toe om die lys rekeninge wat aan jou Android TV-toestel bekend is, te kry. Dit kan dalk rekeninge insluit wat geskep is deur apps wat jy geïnstalleer het."</string>
     <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"Laat die app toe om die lys van rekeninge wat aan die foon bekend is, te kry. Dit kan moontlik enige rekeninge wat geskep is deur apps wat jy geïnstalleer het, insluit."</string>
     <string name="permlab_accessNetworkState" msgid="2349126720783633918">"bekyk netwerkverbindings"</string>
-    <string name="permdesc_accessNetworkState" msgid="4394564702881662849">"Laat die program toe om inligting oor netwerkverbindings, soos watter netwerke bestaan en gekoppel is, te sien."</string>
+    <string name="permdesc_accessNetworkState" msgid="4394564702881662849">"Laat die app toe om inligting oor netwerkverbindings, soos watter netwerke bestaan en gekoppel is, te sien."</string>
     <string name="permlab_createNetworkSockets" msgid="3224420491603590541">"verkry volle netwerktoegang"</string>
     <string name="permdesc_createNetworkSockets" msgid="7722020828749535988">"Laat die program toe om netwerksokke te skep en gepasmaakte netwerkprotokolle te gebruik. Die blaaier en ander programme verskaf reeds die middele waardeur data na die internet gestuur kan word, so hierdie toestemming word nie vereis om data na die internet te stuur nie."</string>
     <string name="permlab_changeNetworkState" msgid="8945711637530425586">"verander netwerkverbinding"</string>
-    <string name="permdesc_changeNetworkState" msgid="649341947816898736">"Laat die program toe om die status van netwerkkonnektiwiteit te verander."</string>
+    <string name="permdesc_changeNetworkState" msgid="649341947816898736">"Laat die app toe om die status van netwerkkonnektiwiteit te verander."</string>
     <string name="permlab_changeTetherState" msgid="9079611809931863861">"verander verbinde konnektiwiteit"</string>
     <string name="permdesc_changeTetherState" msgid="3025129606422533085">"Laat die app toe om die status van verbinde netwerkkonnektiwiteit te verander."</string>
     <string name="permlab_accessWifiState" msgid="5552488500317911052">"bekyk Wi-Fi-verbindings"</string>
-    <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Laat die program toe om inligting oor Wi-Fi-netwerke, soos of Wi-Fi geaktiveer is en die name van gekoppelde Wi-Fi toestelle, te sien."</string>
+    <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Laat die app toe om inligting oor wi-fi-netwerke, soos of wi-fi geaktiveer is en die name van gekoppelde wi-fi-toestelle, te sien."</string>
     <string name="permlab_changeWifiState" msgid="7947824109713181554">"koppel en ontkoppel van Wi-Fi"</string>
     <string name="permdesc_changeWifiState" msgid="7170350070554505384">"Laat die program toe om te koppel aan en te ontkoppel van Wi-Fi-toegangspunte en om veranderings aan Wi-Fi-netwerke se toestelopstellings te maak."</string>
     <string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"laat Wi-Fi-multisendontvangs toe"</string>
@@ -592,14 +592,14 @@
     <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Laat die app toe om pakkette te ontvang wat met multi-uitsendingadresse na alle toestelle op \'n wi-fi-netwerk gestuur is, nie net jou Android TV-toestel nie. Dit gebruik meer krag as nie-multi-uitsendingmodus."</string>
     <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Laat die program toe om pakkies te ontvang wat met behulp van multisaai-adresse na alle toestelle op \'n Wi-Fi-netwerk gestuur is, nie net jou foon nie. Dit gebruik meer krag as die nie-multisaaimodus."</string>
     <string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"gaan in by Bluetooth-instellings"</string>
-    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Laat die program toe om die plaaslike Bluetooth-tablet op te stel, en om met afstandbeheer toestelle saam te bind."</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Laat die app toe om die plaaslike Bluetooth-tablet op te stel, en om met afstandbeheer toestelle saam te bind."</string>
     <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Laat die app toe om Bluetooth op jou Android TV-toestel op te stel, en om afgeleë toestelle te ontdek en met hulle saam te bind."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Laat die program toe om die plaaslike Bluetooth-foon op te stel en te ontdek en met afgeleë toestelle saam te bind."</string>
     <string name="permlab_accessWimaxState" msgid="7029563339012437434">"koppel aan en ontkoppel van WiMAX"</string>
-    <string name="permdesc_accessWimaxState" msgid="5372734776802067708">"Laat die program toe om te bepaal of WiMAX geaktiveer is en of enige WiMAX-netwerke gekoppel is."</string>
+    <string name="permdesc_accessWimaxState" msgid="5372734776802067708">"Laat die app toe om te bepaal of WiMAX geaktiveer is en of enige WiMAX-netwerke gekoppel is."</string>
     <string name="permlab_changeWimaxState" msgid="6223305780806267462">"verander WiMAX-status"</string>
-    <string name="permdesc_changeWimaxState" product="tablet" msgid="4011097664859480108">"Laat die program toe om die tablet aan WiMAX-netwerke te koppel en daarvan te ontkoppel."</string>
-    <string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"Laat die program toe om jou Android TV-toestel aan WiMAX-netwerke te koppel en daarvan te ontkoppel."</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="4011097664859480108">"Laat die app toe om die tablet aan WiMAX-netwerke te koppel en daarvan te ontkoppel."</string>
+    <string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"Laat die app toe om jou Android TV-toestel aan WiMAX-netwerke te koppel en daarvan te ontkoppel."</string>
     <string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"Laat die app toe om die foon aan WiMAX-netwerke te koppel en daarvan te ontkoppel."</string>
     <string name="permlab_bluetooth" msgid="586333280736937209">"bind saam met Bluetooth-toestelle"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Laat die app toe om die opstelling van Bluetooth op die tablet te sien, en om verbindings met saamgebinde toestelle te maak en te aanvaar."</string>
@@ -630,21 +630,21 @@
     <string name="permlab_postNotification" msgid="4875401198597803658">"wys kennisgewings"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Laat die program toe om kennisgewings te wys"</string>
     <string name="permlab_turnScreenOn" msgid="219344053664171492">"skakel die skerm aan"</string>
-    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Laat die program toe om die skerm aan te skakel."</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Laat die app toe om die skerm aan te skakel."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"gebruik biometriese hardeware"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Laat die program toe om biometriese hardeware vir stawing te gebruik"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"bestuur vingerafdrukhardeware"</string>
     <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"Laat die app toe om metodes te benut om vingerafdruktemplate vir gebruik by te voeg en uit te vee."</string>
     <string name="permlab_useFingerprint" msgid="1001421069766751922">"gebruik vingerafdrukhardeware"</string>
-    <string name="permdesc_useFingerprint" msgid="412463055059323742">"Laat die program toe om vingerafdrukhardeware vir stawing te gebruik"</string>
+    <string name="permdesc_useFingerprint" msgid="412463055059323742">"Laat die app toe om vingerafdrukhardeware vir stawing te gebruik"</string>
     <string name="permlab_audioWrite" msgid="8501705294265669405">"wysig jou musiekversameling"</string>
     <string name="permdesc_audioWrite" msgid="8057399517013412431">"Laat die program toe om jou musiekversameling te wysig."</string>
     <string name="permlab_videoWrite" msgid="5940738769586451318">"wysig jou videoversameling"</string>
-    <string name="permdesc_videoWrite" msgid="6124731210613317051">"Laat die program toe om jou videoversameling te wysig."</string>
+    <string name="permdesc_videoWrite" msgid="6124731210613317051">"Laat die app toe om jou videoversameling te wysig."</string>
     <string name="permlab_imagesWrite" msgid="1774555086984985578">"wysig jou fotoversameling"</string>
-    <string name="permdesc_imagesWrite" msgid="5195054463269193317">"Laat die program toe om jou fotoversameling te wysig."</string>
+    <string name="permdesc_imagesWrite" msgid="5195054463269193317">"Laat die app toe om jou fotoversameling te wysig."</string>
     <string name="permlab_mediaLocation" msgid="7368098373378598066">"lees liggings in jou mediaversameling"</string>
-    <string name="permdesc_mediaLocation" msgid="597912899423578138">"Laat die program toe om liggings in jou mediaversameling te lees."</string>
+    <string name="permdesc_mediaLocation" msgid="597912899423578138">"Laat die app toe om liggings in jou mediaversameling te lees."</string>
     <string name="biometric_app_setting_name" msgid="3339209978734534457">"Gebruik biometrie"</string>
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gebruik biometrie of skermslot"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifieer dat dit jy is"</string>
@@ -764,17 +764,17 @@
     <string name="permlab_readSyncSettings" msgid="6250532864893156277">"lees sinkroniseer-instellings"</string>
     <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"Laat die app toe om die sinkroniseringinstellings van \'n rekening te lees. Byvoorbeeld, dit kan bepaal of die People-app met \'n rekening gesinkroniseer is."</string>
     <string name="permlab_writeSyncSettings" msgid="6583154300780427399">"wissel tussen sinkronisasie aan en af"</string>
-    <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"Laat \'n program toe om die sinkroniseringinstellings van \'n rekening te verander. Byvoorbeeld, dit kan gebruik word om sinkronisasie van die People-program met \'n ander rekening te aktiveer."</string>
+    <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"Laat \'n app toe om die sinkroniseringinstellings van \'n rekening te verander. Byvoorbeeld, dit kan gebruik word om sinkronisasie van die People-app met \'n ander rekening te aktiveer."</string>
     <string name="permlab_readSyncStats" msgid="3747407238320105332">"lees sinkroniseerstatistiek"</string>
-    <string name="permdesc_readSyncStats" msgid="3867809926567379434">"Laat \'n program toe om die sinkroniseringstatistieke van \'n rekening te lees, insluitend die geskiedenis van sinkroniseringgebeure en hoeveel data gesinkroniseer is."</string>
+    <string name="permdesc_readSyncStats" msgid="3867809926567379434">"Laat \'n app toe om die sinkroniseringstatistieke van \'n rekening te lees, insluitend die geskiedenis van sinkroniseringgebeure en hoeveel data gesinkroniseer is."</string>
     <string name="permlab_sdcardRead" msgid="5791467020950064920">"lees jou gedeelde berging se inhoud"</string>
-    <string name="permdesc_sdcardRead" msgid="6872973242228240382">"Laat die program toe om jou gedeelde berging se inhoud te lees."</string>
+    <string name="permdesc_sdcardRead" msgid="6872973242228240382">"Laat die app toe om jou gedeelde berging se inhoud te lees."</string>
     <string name="permlab_readMediaAudio" msgid="8723513075731763810">"lees oudiolêers in gedeelde berging"</string>
-    <string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Laat die program toe om oudiolêers in jou gedeelde berging te lees."</string>
+    <string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Laat die app toe om oudiolêers in jou gedeelde berging te lees."</string>
     <string name="permlab_readMediaVideo" msgid="7768003311260655007">"lees videolêers in gedeelde berging"</string>
-    <string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Laat die program toe om videolêers in jou gedeelde berging te lees."</string>
+    <string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Laat die app toe om videolêers in jou gedeelde berging te lees."</string>
     <string name="permlab_readMediaImages" msgid="4057590631020986789">"lees prentlêers in gedeelde berging"</string>
-    <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Laat die program toe om prentlêers in jou gedeelde berging te lees."</string>
+    <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Laat die app toe om prentlêers in jou gedeelde berging te lees."</string>
     <string name="permlab_readVisualUserSelect" msgid="5516204215354667586">"lees prent- en videolêers wat gebruiker in gedeelde berging kies"</string>
     <string name="permdesc_readVisualUserSelect" msgid="8027174717714968217">"Laat die app toe om prent- en videolêers te lees wat jy in jou gedeelde berging kies."</string>
     <string name="permlab_sdcardWrite" msgid="4863021819671416668">"verander of vee jou gedeelde berging se inhoud uit"</string>
@@ -782,23 +782,23 @@
     <string name="permlab_use_sip" msgid="8250774565189337477">"maak en/of ontvang SIP-oproepe"</string>
     <string name="permdesc_use_sip" msgid="3590270893253204451">"Laat die app toe om SIP-oproepe te maak en te ontvang."</string>
     <string name="permlab_register_sim_subscription" msgid="1653054249287576161">"registreer nuwe telekommunikasie-SIM-verbindings"</string>
-    <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"Laat die program toe om nuwe telekommunikasie-SIM-verbindings te registreer."</string>
+    <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"Laat die app toe om nuwe telekommunikasie-SIM-verbindings te registreer."</string>
     <string name="permlab_register_call_provider" msgid="6135073566140050702">"registreer nuwe telekommunikasieverbindings"</string>
-    <string name="permdesc_register_call_provider" msgid="4201429251459068613">"Laat die program toe om nuwe telekommunikasieverbindings te registreer."</string>
+    <string name="permdesc_register_call_provider" msgid="4201429251459068613">"Laat die app toe om nuwe telekommunikasieverbindings te registreer."</string>
     <string name="permlab_connection_manager" msgid="3179365584691166915">"bestuur telekom-verbindings"</string>
     <string name="permdesc_connection_manager" msgid="1426093604238937733">"Laat die app toe om telekom-verbindings te bestuur."</string>
     <string name="permlab_bind_incall_service" msgid="5990625112603493016">"beleef interaksie met inoproep-skerm"</string>
-    <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"Laat die program beheer wanneer en hoe die gebruiker die inoproep-skerm sien."</string>
+    <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"Laat die app beheer wanneer en hoe die gebruiker die inoproep-skerm sien."</string>
     <string name="permlab_bind_connection_service" msgid="5409268245525024736">"werk met telefoniedienste saam"</string>
-    <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Laat die program toe om met telefoniedienste saam te werk om oproepe te maak of ontvang."</string>
+    <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Laat die app toe om met telefoniedienste saam te werk om oproepe te maak of ontvang."</string>
     <string name="permlab_control_incall_experience" msgid="6436863486094352987">"bied \'n inoproep-gebruikerervaring"</string>
-    <string name="permdesc_control_incall_experience" msgid="5896723643771737534">"Laat die program toe om \'n inoproep-gebruikerervaring te bied."</string>
+    <string name="permdesc_control_incall_experience" msgid="5896723643771737534">"Laat die app toe om \'n inoproep-gebruikerervaring te bied."</string>
     <string name="permlab_readNetworkUsageHistory" msgid="8470402862501573795">"lees netwerkgebruik-geskiedenis"</string>
     <string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"Laat die app toe om historiese netwerkgebruik vir spesifieke netwerke en apps te lees."</string>
     <string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"bestuur netwerkbeleid"</string>
     <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"Laat die app toe om netwerkbeleide te bestuur en app-spesifieke reëls te definieer."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"verander verrekening van netwerkgebruik"</string>
-    <string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"Laat die program toe om te verander hoe netwerkgebruik teenoor programme gemeet word. Nie vir gebruik deur normale programme nie."</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"Laat die app toe om te verander hoe netwerkgebruik teenoor apps gemeet word. Nie vir gebruik deur normale apps nie."</string>
     <string name="permlab_accessNotifications" msgid="7130360248191984741">"kry toegang tot kennisgewings"</string>
     <string name="permdesc_accessNotifications" msgid="761730149268789668">"Laat die program toe om kennisgewings op te haal, te bestudeer en te verwyder, insluitende die kennisgewings wat deur ander programme geplaas is."</string>
     <string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"bind aan \'n kennisgewingluisteraardiens"</string>
@@ -814,11 +814,11 @@
     <string name="permlab_setInputCalibration" msgid="932069700285223434">"verander invoertoestelkalibrasie"</string>
     <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"Laat die app toe om die kalibrasieparameters van die raakskerm te wysig. Dit behoort nooit vir normale apps nodig te wees nie."</string>
     <string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"gaan in by DRM-sertifikate"</string>
-    <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Laat \'n program toe om DRM-sertifikate op te stel en te gebruik. Behoort nooit vir normale programme nodig te wees nie."</string>
+    <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Laat \'n app toe om DRM-sertifikate op te stel en te gebruik. Dit behoort nooit vir normale apps nodig te wees nie."</string>
     <string name="permlab_handoverStatus" msgid="7620438488137057281">"ontvang Android Straal-oordragstatus"</string>
-    <string name="permdesc_handoverStatus" msgid="3842269451732571070">"Laat hierdie program toe om inligting oor huidige Android Straal-oordragte te ontvang."</string>
+    <string name="permdesc_handoverStatus" msgid="3842269451732571070">"Laat hierdie app toe om inligting oor huidige Android Straal-oordragte te ontvang."</string>
     <string name="permlab_removeDrmCertificates" msgid="710576248717404416">"verwyder DRM-sertifikate"</string>
-    <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Laat \'n program toe om DRM-sertifikate te verwyder. Behoort nooit vir gewone programme nodig te wees nie."</string>
+    <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Laat \'n app toe om DRM-sertifikate te verwyder. Dit behoort nooit vir gewone apps nodig te wees nie."</string>
     <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"bind aan \'n diensverskaffer-boodskapdiens"</string>
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Dit laat die houer toe om aan die top-koppelvlak van \'n diensverskaffer-boodskapdiens te bind. Behoort nooit vir gewone programme nodig te wees nie."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"verbind aan diensverskafferdienste"</string>
@@ -1106,7 +1106,7 @@
     <string name="permlab_setAlarm" msgid="1158001610254173567">"stel \'n wekker"</string>
     <string name="permdesc_setAlarm" msgid="2185033720060109640">"Laat die app toe om \'n alarm in \'n geïnstalleerde wekkerapp te stel. Sommige wekkerapps werk dalk nie met hierdie funksie nie."</string>
     <string name="permlab_addVoicemail" msgid="4770245808840814471">"voeg stemboodskap by"</string>
-    <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Laat die program toe om boodskappe by te voeg by jou stempos-inkassie."</string>
+    <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Laat die app toe om boodskappe by te voeg by jou stempos-inkassie."</string>
     <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> het van jou knipbord af geplak"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Meer"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Kieslys+"</string>
@@ -1237,7 +1237,7 @@
     <string name="low_internal_storage_view_text" msgid="8172166728369697835">"Sommige stelselfunksies werk moontlik nie"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"Nie genoeg berging vir die stelsel nie. Maak seker jy het 250 MB spasie beskikbaar en herbegin."</string>
     <string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> loop tans"</string>
-    <string name="app_running_notification_text" msgid="5120815883400228566">"Tik vir meer inligting of om die program te stop."</string>
+    <string name="app_running_notification_text" msgid="5120815883400228566">"Tik vir meer inligting of om die app te stop."</string>
     <string name="ok" msgid="2646370155170753815">"OK"</string>
     <string name="cancel" msgid="6908697720451760115">"Kanselleer"</string>
     <string name="yes" msgid="9069828999585032361">"OK"</string>
@@ -1279,7 +1279,7 @@
     <string name="whichImageCaptureApplicationNamed" msgid="8820702441847612202">"Vang prent vas met %1$s"</string>
     <string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"Vang prent vas"</string>
     <string name="alwaysUse" msgid="3153558199076112903">"Gebruik hierdie aksie by verstek."</string>
-    <string name="use_a_different_app" msgid="4987790276170972776">"Gebruik \'n ander program"</string>
+    <string name="use_a_different_app" msgid="4987790276170972776">"Gebruik \'n ander app"</string>
     <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Vee die verstek instelling uit in Stelselinstellings &gt; Programme &gt; Afgelaai."</string>
     <string name="chooseActivity" msgid="8563390197659779956">"Kies \'n handeling"</string>
     <string name="chooseUsbActivity" msgid="2096269989990986612">"Kies \'n app vir die USB-toestel"</string>
@@ -1303,7 +1303,7 @@
     <string name="report" msgid="2149194372340349521">"Verslag"</string>
     <string name="wait" msgid="7765985809494033348">"Wag"</string>
     <string name="webpage_unresponsive" msgid="7850879412195273433">"Die bladsy reageer nie meer nie.\n\nWil jy dit toemaak?"</string>
-    <string name="launch_warning_title" msgid="6725456009564953595">"Program herlei"</string>
+    <string name="launch_warning_title" msgid="6725456009564953595">"App is herlei"</string>
     <string name="launch_warning_replace" msgid="3073392976283203402">"<xliff:g id="APP_NAME">%1$s</xliff:g> loop nou."</string>
     <string name="launch_warning_original" msgid="3332206576800169626">"<xliff:g id="APP_NAME">%1$s</xliff:g> is oorspronklik laat loop."</string>
     <string name="screen_compat_mode_scale" msgid="8627359598437527726">"Skaal"</string>
@@ -1314,7 +1314,7 @@
     <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> is gebou vir \'n onversoenbare weergawe van die Android-bedryfstelsel en kan dalk op \'n onverwagte manier reageer. \'n Opgedateerde weergawe van die program is dalk beskikbaar."</string>
     <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Wys altyd"</string>
     <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Kyk vir opdatering"</string>
-    <string name="smv_application" msgid="3775183542777792638">"Die program <xliff:g id="APPLICATION">%1$s</xliff:g> (proses <xliff:g id="PROCESS">%2$s</xliff:g>) het sy selfopgelegde StrictMode-beleid oortree."</string>
+    <string name="smv_application" msgid="3775183542777792638">"Die app <xliff:g id="APPLICATION">%1$s</xliff:g> (proses <xliff:g id="PROCESS">%2$s</xliff:g>) het sy selfopgelegde StrictMode-beleid oortree."</string>
     <string name="smv_process" msgid="1398801497130695446">"Die proses <xliff:g id="PROCESS">%1$s</xliff:g> het die selfopgelegde StrictMode-beleid geskend."</string>
     <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Foon dateer tans op …"</string>
     <string name="android_upgrading_title" product="tablet" msgid="4268417249079938805">"Tablet dateer tans oop …"</string>
@@ -1397,7 +1397,7 @@
     <string name="decline" msgid="6490507610282145874">"Weier"</string>
     <string name="select_character" msgid="3352797107930786979">"Voeg karakter in"</string>
     <string name="sms_control_title" msgid="4748684259903148341">"Stuur SMS-boodskappe"</string>
-    <string name="sms_control_message" msgid="6574313876316388239">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; stuur \'n groot aantal SMS-boodskappe. Wil jy hierdie program toelaat om voort te gaan om boodskappe te stuur?"</string>
+    <string name="sms_control_message" msgid="6574313876316388239">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; stuur \'n groot aantal SMS-boodskappe. Wil jy hierdie app toelaat om voort te gaan om boodskappe te stuur?"</string>
     <string name="sms_control_yes" msgid="4858845109269524622">"Laat toe"</string>
     <string name="sms_control_no" msgid="4845717880040355570">"Weier"</string>
     <string name="sms_short_code_confirm_message" msgid="1385416688897538724">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; wil \'n boodskap na &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt; stuur."</string>
@@ -1417,8 +1417,8 @@
     <string name="sim_restart_button" msgid="8481803851341190038">"Herbegin"</string>
     <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"Aktiveer mobiele diens"</string>
     <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Laai die diensverskafferprogram af om jou nuwe SIM te aktiveer"</string>
-    <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Laai die <xliff:g id="APP_NAME">%1$s</xliff:g>-program af om jou nuwe SIM te aktiveer"</string>
-    <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Laai program af"</string>
+    <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Laai die <xliff:g id="APP_NAME">%1$s</xliff:g>-app af om jou nuwe SIM te aktiveer"</string>
+    <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Laai app af"</string>
     <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nuwe SIM is ingesit"</string>
     <string name="carrier_app_notification_text" msgid="6567057546341958637">"Tik om dit op te stel"</string>
     <string name="time_picker_dialog_title" msgid="9053376764985220821">"Stel tyd"</string>
@@ -1533,13 +1533,13 @@
     <string name="permlab_route_media_output" msgid="8048124531439513118">"roeteer media-uitvoer"</string>
     <string name="permdesc_route_media_output" msgid="1759683269387729675">"Laat \'n app toe om media-uitvoere na ander eksterne toestelle te roeteer."</string>
     <string name="permlab_readInstallSessions" msgid="7279049337895583621">"lees installeersessies"</string>
-    <string name="permdesc_readInstallSessions" msgid="4012608316610763473">"Laat \'n program toe om installasiesessies te lees. Dit laat dit toe om besonderhede van aktiewe pakketinstallasies te sien."</string>
+    <string name="permdesc_readInstallSessions" msgid="4012608316610763473">"Laat \'n app toe om installasiesessies te lees. Dit laat dit toe om besonderhede van aktiewe pakketinstallasies te sien."</string>
     <string name="permlab_requestInstallPackages" msgid="7600020863445351154">"versoek installeerpakkette"</string>
-    <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"Laat \'n program toe om te versoek dat pakkette geïnstalleer word."</string>
+    <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"Laat \'n app toe om te versoek dat pakkette geïnstalleer word."</string>
     <string name="permlab_requestDeletePackages" msgid="2541172829260106795">"versoek uitvee van pakkette"</string>
-    <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Laat \'n program toe om te versoek dat pakkette uitgevee word."</string>
+    <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Laat \'n app toe om te versoek dat pakkette uitgevee word."</string>
     <string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"vra om batteryoptimerings te ignoreer"</string>
-    <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Laat \'n program toe om toestemming te vra om batteryoptimerings vir daardie program ignoreer."</string>
+    <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Laat \'n app toe om toestemming te vra om batteryoptimerings vir daardie app te ignoreer."</string>
     <string name="permlab_queryAllPackages" msgid="2928450604653281650">"navraag oor alle pakkette"</string>
     <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Laat \'n program toe om alle geïnstalleerde pakette te sien."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Klop twee keer vir zoembeheer"</string>
@@ -1561,7 +1561,7 @@
     <string name="permission_request_notification_title" msgid="1810025922441048273">"Toestemming versoek"</string>
     <string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"Toestemming versoek\nvir rekening <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="permission_request_notification_for_app_with_subtitle" msgid="1298704005732851350">"Toestemming versoek deur <xliff:g id="APP">%1$s</xliff:g>\nvir rekening <xliff:g id="ACCOUNT">%2$s</xliff:g>"</string>
-    <string name="forward_intent_to_owner" msgid="4620359037192871015">"Jy gebruik hierdie program buite jou werkprofiel"</string>
+    <string name="forward_intent_to_owner" msgid="4620359037192871015">"Jy gebruik hierdie app buite jou werkprofiel"</string>
     <string name="forward_intent_to_work" msgid="3620262405636021151">"Jy gebruik tans hierdie app in jou werkprofiel"</string>
     <string name="input_method_binding_label" msgid="1166731601721983656">"Invoermetode"</string>
     <string name="sync_binding_label" msgid="469249309424662147">"Sinkroniseer"</string>
@@ -2068,9 +2068,9 @@
     <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"Hierdie app versoek tans bykomende toestemmings, maar toestemmings kan nie in ’n stromingsessie verleen word nie. Verleen eers die toestemming op jou Android TV-toestel."</string>
     <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"Hierdie app versoek tans bykomende toestemmings, maar toestemmings kan nie in ’n stromingsessie verleen word nie. Verleen eers die toestemming op jou tablet."</string>
     <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"Hierdie app versoek tans bykomende toestemmings, maar toestemmings kan nie in ’n stromingsessie verleen word nie. Verleen eers die toestemming op jou foon."</string>
-    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Hierdie program versoek tans bykomende sekuriteit. Probeer eerder op jou Android TV-toestel."</string>
-    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Hierdie program versoek tans bykomende sekuriteit. Probeer eerder op jou tablet."</string>
-    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Hierdie program versoek tans bykomende sekuriteit. Probeer eerder op jou foon."</string>
+    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Hierdie app versoek tans bykomende sekuriteit. Probeer eerder op jou Android TV-toestel."</string>
+    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Hierdie app versoek tans bykomende sekuriteit. Probeer eerder op jou tablet."</string>
+    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Hierdie app versoek tans bykomende sekuriteit. Probeer eerder op jou foon."</string>
     <string name="app_streaming_blocked_message_for_settings_dialog" product="tv" msgid="820334666354451145">"Jy kan nie op jou <xliff:g id="DEVICE">%1$s</xliff:g> toegang hiertoe kry nie. Probeer eerder op jou Android TV-toestel."</string>
     <string name="app_streaming_blocked_message_for_settings_dialog" product="tablet" msgid="3286849551133045896">"Jy kan nie op jou <xliff:g id="DEVICE">%1$s</xliff:g> toegang hiertoe kry nie. Probeer eerder op jou tablet."</string>
     <string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Jy kan nie op jou <xliff:g id="DEVICE">%1$s</xliff:g> toegang hiertoe kry nie. Probeer eerder op jou foon."</string>
@@ -2157,7 +2157,7 @@
     <string name="popup_window_default_title" msgid="6907717596694826919">"Opspringvenster"</string>
     <string name="slice_more_content" msgid="3377367737876888459">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
     <string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"Programweergawe is afgegradeer, of is nie met hierdie kortpad versoenbaar nie"</string>
-    <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Kon nie die kortpad teruglaai nie omdat die program nie rugsteun en teruglaai steun nie"</string>
+    <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Kon nie die kortpad teruglaai nie omdat die app nie rugsteun en teruglaai steun nie"</string>
     <string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Kon nie teruglaai nie omdat programondertekening nie ooreenstem nie"</string>
     <string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"Kon nie kortpad teruglaai nie"</string>
     <string name="shortcut_disabled_reason_unknown" msgid="753074793553599166">"Kortpad is gedeaktiveer"</string>
@@ -2403,8 +2403,8 @@
     <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> is vertaal."</string>
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Boodskap is vertaal uit <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> in <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Agtergrondaktiwiteit"</string>
-    <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"’n Program maak tans die battery pap"</string>
-    <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"’n Program is nog aktief"</string>
+    <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"’n App maak tans die battery pap"</string>
+    <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"’n App is nog aktief"</string>
     <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"<xliff:g id="APP">%1$s</xliff:g> loop tans op die agtergrond. Tik om batterygebruik te bestuur."</string>
     <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> kan batterylewe beïnvloed. Tik om aktiewe programme na te gaan."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Gaan aktiewe programme na"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index baa54bb..a212808 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1158,38 +1158,22 @@
     <string name="duration_hours_shortest_future" msgid="2979276794547981674">"in <xliff:g id="COUNT">%d</xliff:g>h"</string>
     <string name="duration_days_shortest_future" msgid="3392722163935571543">"in <xliff:g id="COUNT">%d</xliff:g>d"</string>
     <string name="duration_years_shortest_future" msgid="5537464088352970388">"in <xliff:g id="COUNT">%d</xliff:g>y"</string>
-    <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
-    <skip />
-    <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
-    <skip />
-    <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
-    <skip />
-    <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium (1465359726485910115) -->
-    <skip />
-    <!-- no translation found for duration_days_medium (5994225628248661388) -->
-    <skip />
-    <!-- no translation found for duration_years_medium (734023884353592526) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_past (893797065424596243) -->
-    <skip />
+    <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"<xliff:g id="COUNT">%d</xliff:g>m ago"</string>
+    <string name="duration_hours_shortest_past" msgid="2098397414186628489">"<xliff:g id="COUNT">%d</xliff:g>h ago"</string>
+    <string name="duration_days_shortest_past" msgid="1832006037955897625">"<xliff:g id="COUNT">%d</xliff:g>d ago"</string>
+    <string name="duration_years_shortest_past" msgid="6168256514200469291">"<xliff:g id="COUNT">%d</xliff:g>y ago"</string>
+    <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g>min"</string>
+    <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g>hr"</string>
+    <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g>d"</string>
+    <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g>yr"</string>
+    <string name="duration_minutes_medium_future" msgid="2750894988731934402">"in <xliff:g id="COUNT">%d</xliff:g>min"</string>
+    <string name="duration_hours_medium_future" msgid="6050833881463849764">"in <xliff:g id="COUNT">%d</xliff:g>hr"</string>
+    <string name="duration_days_medium_future" msgid="1700821545602729963">"in <xliff:g id="COUNT">%d</xliff:g>d"</string>
+    <string name="duration_years_medium_future" msgid="3281018940397120166">"in <xliff:g id="COUNT">%d</xliff:g>yr"</string>
+    <string name="duration_minutes_medium_past" msgid="7400424340181947714">"<xliff:g id="COUNT">%d</xliff:g>min ago"</string>
+    <string name="duration_hours_medium_past" msgid="6709441336035202617">"<xliff:g id="COUNT">%d</xliff:g>hr ago"</string>
+    <string name="duration_days_medium_past" msgid="5748156261134344532">"<xliff:g id="COUNT">%d</xliff:g>d ago"</string>
+    <string name="duration_years_medium_past" msgid="893797065424596243">"<xliff:g id="COUNT">%d</xliff:g>yr ago"</string>
     <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# minute ago}other{# minutes ago}}"</string>
     <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# hour ago}other{# hours ago}}"</string>
     <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# day ago}other{# days ago}}"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 07fa8bf..3d7c91c 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1158,38 +1158,22 @@
     <string name="duration_hours_shortest_future" msgid="2979276794547981674">"<xliff:g id="COUNT">%d</xliff:g> 時間後"</string>
     <string name="duration_days_shortest_future" msgid="3392722163935571543">"<xliff:g id="COUNT">%d</xliff:g> 日後"</string>
     <string name="duration_years_shortest_future" msgid="5537464088352970388">"<xliff:g id="COUNT">%d</xliff:g> 年後"</string>
-    <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
-    <skip />
-    <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
-    <skip />
-    <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
-    <skip />
-    <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium (1465359726485910115) -->
-    <skip />
-    <!-- no translation found for duration_days_medium (5994225628248661388) -->
-    <skip />
-    <!-- no translation found for duration_years_medium (734023884353592526) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_past (893797065424596243) -->
-    <skip />
+    <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"<xliff:g id="COUNT">%d</xliff:g> 分前"</string>
+    <string name="duration_hours_shortest_past" msgid="2098397414186628489">"<xliff:g id="COUNT">%d</xliff:g> 時間前"</string>
+    <string name="duration_days_shortest_past" msgid="1832006037955897625">"<xliff:g id="COUNT">%d</xliff:g> 日前"</string>
+    <string name="duration_years_shortest_past" msgid="6168256514200469291">"<xliff:g id="COUNT">%d</xliff:g> 年前"</string>
+    <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g> 分"</string>
+    <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g> 時間"</string>
+    <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> 日"</string>
+    <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g> 年"</string>
+    <string name="duration_minutes_medium_future" msgid="2750894988731934402">"あと <xliff:g id="COUNT">%d</xliff:g> 分"</string>
+    <string name="duration_hours_medium_future" msgid="6050833881463849764">"あと <xliff:g id="COUNT">%d</xliff:g> 時間"</string>
+    <string name="duration_days_medium_future" msgid="1700821545602729963">"あと <xliff:g id="COUNT">%d</xliff:g> 日"</string>
+    <string name="duration_years_medium_future" msgid="3281018940397120166">"あと <xliff:g id="COUNT">%d</xliff:g> 年"</string>
+    <string name="duration_minutes_medium_past" msgid="7400424340181947714">"<xliff:g id="COUNT">%d</xliff:g> 分前"</string>
+    <string name="duration_hours_medium_past" msgid="6709441336035202617">"<xliff:g id="COUNT">%d</xliff:g> 時間前"</string>
+    <string name="duration_days_medium_past" msgid="5748156261134344532">"<xliff:g id="COUNT">%d</xliff:g> 日前"</string>
+    <string name="duration_years_medium_past" msgid="893797065424596243">"<xliff:g id="COUNT">%d</xliff:g> 年前"</string>
     <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# 分前}other{# 分前}}"</string>
     <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# 時間前}other{# 時間前}}"</string>
     <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# 日前}other{# 日前}}"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 3849690..49b4bfc 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1158,38 +1158,22 @@
     <string name="duration_hours_shortest_future" msgid="2979276794547981674">"<xliff:g id="COUNT">%d</xliff:g> сағ кейін"</string>
     <string name="duration_days_shortest_future" msgid="3392722163935571543">"<xliff:g id="COUNT">%d</xliff:g> күннен кейін"</string>
     <string name="duration_years_shortest_future" msgid="5537464088352970388">"<xliff:g id="COUNT">%d</xliff:g> жылдан кейін"</string>
-    <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
-    <skip />
-    <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
-    <skip />
-    <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
-    <skip />
-    <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium (1465359726485910115) -->
-    <skip />
-    <!-- no translation found for duration_days_medium (5994225628248661388) -->
-    <skip />
-    <!-- no translation found for duration_years_medium (734023884353592526) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_past (893797065424596243) -->
-    <skip />
+    <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"<xliff:g id="COUNT">%d</xliff:g> мин бұрын"</string>
+    <string name="duration_hours_shortest_past" msgid="2098397414186628489">"<xliff:g id="COUNT">%d</xliff:g> сағ бұрын"</string>
+    <string name="duration_days_shortest_past" msgid="1832006037955897625">"<xliff:g id="COUNT">%d</xliff:g> күн бұрын"</string>
+    <string name="duration_years_shortest_past" msgid="6168256514200469291">"<xliff:g id="COUNT">%d</xliff:g> жыл бұрын"</string>
+    <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g> мин"</string>
+    <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g> сағ"</string>
+    <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> күн"</string>
+    <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g> жыл"</string>
+    <string name="duration_minutes_medium_future" msgid="2750894988731934402">"<xliff:g id="COUNT">%d</xliff:g> минуттан кейін"</string>
+    <string name="duration_hours_medium_future" msgid="6050833881463849764">"<xliff:g id="COUNT">%d</xliff:g> сағаттан кейін"</string>
+    <string name="duration_days_medium_future" msgid="1700821545602729963">"<xliff:g id="COUNT">%d</xliff:g> күннен кейін"</string>
+    <string name="duration_years_medium_future" msgid="3281018940397120166">"<xliff:g id="COUNT">%d</xliff:g> жылдан кейін"</string>
+    <string name="duration_minutes_medium_past" msgid="7400424340181947714">"<xliff:g id="COUNT">%d</xliff:g> мин бұрын"</string>
+    <string name="duration_hours_medium_past" msgid="6709441336035202617">"<xliff:g id="COUNT">%d</xliff:g> сағ бұрын"</string>
+    <string name="duration_days_medium_past" msgid="5748156261134344532">"<xliff:g id="COUNT">%d</xliff:g> күн бұрын"</string>
+    <string name="duration_years_medium_past" msgid="893797065424596243">"<xliff:g id="COUNT">%d</xliff:g> жыл бұрын"</string>
     <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# минут бұрын}other{# минут бұрын}}"</string>
     <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# сағат бұрын}other{# сағат бұрын}}"</string>
     <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# күн бұрын}other{# күн бұрын}}"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 85352bc..ad62f42 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -561,13 +561,13 @@
     <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"ಟ್ಯಾಬ್ಲೆಟ್‌ನ ಇನ್‌ಫ್ರಾರೆಡ್ ಸಂವಾಹಕವನ್ನು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"ನಿಮ್ಮ Android TV ಸಾಧನದ ಇನ್‌ಫ್ರಾರೆಡ್ ಟ್ರಾನ್ಸ್‌ಮೀಟರ್ ಅನ್ನು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"ಫೋನ್‌ನ ಇನ್‌ಫ್ರಾರೆಡ್ ಸಂವಾಹಕವನ್ನು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
-    <string name="permlab_setWallpaper" msgid="6959514622698794511">"ವಾಲ್‌ಪೇಪರ್ ಹೊಂದಿಸಿ"</string>
+    <string name="permlab_setWallpaper" msgid="6959514622698794511">"ವಾಲ್‌ಪೇಪರ್ ಸೆಟ್ ಮಾಡಿ"</string>
     <string name="permdesc_setWallpaper" msgid="2973996714129021397">"ಸಿಸ್ಟಂ ವಾಲ್‌ಪೇಪರ್‌ ಹೊಂದಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permlab_accessHiddenProfile" msgid="8607094418491556823">"ಮರೆಮಾಡಲಾದ ಪ್ರೊಫೈಲ್‌ಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಿ"</string>
     <string name="permdesc_accessHiddenProfile" msgid="1543153202481009676">"ಮರೆಮಾಡಲಾದ ಪ್ರೊಫೈಲ್‌ಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permlab_setWallpaperHints" msgid="1153485176642032714">"ನಿಮ್ಮ ವಾಲ್‍ಪೇಪರ್ ಗಾತ್ರವನ್ನು ಸರಿಹೊಂದಿಸಿ"</string>
     <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"ಸಿಸ್ಟಂ ವಾಲ್‌ಪೇಪರ್‌‌ ಗಾತ್ರದ ಸುಳಿವುಗಳನ್ನು ಹೊಂದಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
-    <string name="permlab_setTimeZone" msgid="7922618798611542432">"ಸಮಯದ ವಲಯವನ್ನು ಹೊಂದಿಸಿ"</string>
+    <string name="permlab_setTimeZone" msgid="7922618798611542432">"ಸಮಯದ ವಲಯವನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
     <string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"ಟ್ಯಾಬ್ಲೆಟ್‌‌ನ ಸಮಯ ವಲಯವನ್ನು ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"ನಿಮ್ಮ Android TV ಸಾಧನದ ಸಮಯವಲಯವನ್ನು ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"ಫೋನ್‌ನ ಸಮಯ ವಲಯವನ್ನು ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
@@ -837,7 +837,7 @@
     <string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"ಬಳಕೆದಾರರ ಕ್ರಿಯೆಯಿಲ್ಲದೆ ಈ ಹಿಂದೆ ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿದ ಆ್ಯಪ್ ಅನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಲು ಹೋಲ್ಡರ್ ಅನ್ನು ಅನುಮತಿಸುತ್ತದೆ"</string>
     <string name="permlab_writeVerificationStateE2eeContactKeys" msgid="3990742344778360457">"ಇತರ ಆ್ಯಪ್‌ಗಳ ಮಾಲೀಕತ್ವದ E2EE ಸಂಪರ್ಕ ಕೀಗಳ ಪರಿಶೀಲನೆಯ ಸ್ಥಿತಿಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಿ"</string>
     <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"ಇತರ ಆ್ಯಪ್‌ಗಳ ಮಾಲೀಕತ್ವದ E2EE ಸಂಪರ್ಕ ಕೀಗಳ ಪರಿಶೀಲನೆಯ ಸ್ಥಿತಿಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
-    <string name="policylab_limitPassword" msgid="4851829918814422199">"ಪಾಸ್‌ವರ್ಡ್ ನಿಮಯಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
+    <string name="policylab_limitPassword" msgid="4851829918814422199">"ಪಾಸ್‌ವರ್ಡ್ ನಿಮಯಗಳನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"ಸ್ಕ್ರೀನ್ ಲಾಕ್‌ನಲ್ಲಿನ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು ಮತ್ತು ಪಿನ್‌ಗಳ ಅನುಮತಿಸಲಾದ ಅಕ್ಷರಗಳ ಪ್ರಮಾಣವನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
     <string name="policylab_watchLogin" msgid="7599669460083719504">"ಪರದೆಯ ಅನ್‌ಲಾಕ್ ಪ್ರಯತ್ನಗಳನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ಸ್ಕ್ರೀನ್ ಅನ್‌ಲಾಕ್‌ ಮಾಡುವಾಗ ತಪ್ಪಾಗಿ ಟೈಪ್‌ ಮಾಡಿದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ, ಮತ್ತು ಹಲವಾರು ತಪ್ಪಾದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ಟೈಪ್‌ ಮಾಡಿದ್ದರೆ ಟ್ಯಾಬ್ಲೆಟ್‌ ಅನ್ನು ಲಾಕ್‌ ಮಾಡಿ ಅಥವಾ ಟ್ಯಾಬ್ಲೆಟ್‌ನ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
@@ -863,11 +863,11 @@
     <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"ಎಚ್ಚರಿಕೆ ಇಲ್ಲದೆ ಈ Android TV ಸಾಧನದಲ್ಲಿನ ಈ ಬಳಕೆದಾರರ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕುತ್ತದೆ."</string>
     <string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"ಎಚ್ಚರಿಕೆಯಿಲ್ಲದೆ ಈ ಇನ್ಫೋಟೈನ್‌ಮೆಂಟ್ ಸಿಸ್ಟಂನಲ್ಲಿ ಈ ಪ್ರೊಫೈಲ್‌ನ ಡೇಟಾವನ್ನು ಅಳಿಸಿ."</string>
     <string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"ಯಾವುದೇ ಸೂಚನೆ ಇಲ್ಲದೆ ಈ ಫೋನ್‌ನಲ್ಲಿ ಈ ಬಳಕೆದಾರರ ಡೇಟಾವನ್ನು ಅಳಿಸಿ."</string>
-    <string name="policylab_setGlobalProxy" msgid="215332221188670221">"ಸಾಧನವನ್ನು ಜಾಗತಿಕ ಪ್ರಾಕ್ಸಿಗೆ ಹೊಂದಿಸಿ"</string>
-    <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"ನೀತಿಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿದಾಗ ಬಳಸಬೇಕಾದ ಸಾಧನದ ಜಾಗತಿಕ ಪ್ರಾಕ್ಸಿಯನ್ನು ಹೊಂದಿಸಿ. ಸಾಧನದ ಮಾಲೀಕರು ಮಾತ್ರ ಜಾಗತಿಕ ಪ್ರಾಕ್ಸಿಯನ್ನು ಹೊಂದಿಸಬಹುದಾಗಿರುತ್ತದೆ."</string>
-    <string name="policylab_expirePassword" msgid="6015404400532459169">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಪಾಸ್‌ವರ್ಡ್ ಮುಕ್ತಾಯವನ್ನು ಹೊಂದಿಸಿ"</string>
+    <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">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಪಾಸ್‌ವರ್ಡ್, ಪಿನ್, ಅಥವಾ ನಮೂನೆಯನ್ನು ಹೆಚ್ಚು ಪದೆ ಪದೇ ಬದಲಾಯಿಸಬೇಕಾಗಿರುತ್ತದೆ ಎಂಬುದನ್ನು ಬದಲಾಯಿಸಿ."</string>
-    <string name="policylab_encryptedStorage" msgid="9012936958126670110">"ಸಂಗ್ರಹಣೆ ಎನ್‌ಕ್ರಿಪ್ಶನ್ ಹೊಂದಿಸಿ"</string>
+    <string name="policylab_encryptedStorage" msgid="9012936958126670110">"ಸಂಗ್ರಹಣೆ ಎನ್‌ಕ್ರಿಪ್ಶನ್ ಸೆಟ್ ಮಾಡಿ"</string>
     <string name="policydesc_encryptedStorage" msgid="1102516950740375617">"ಸಂಗ್ರಹಿಸಿರುವ ಆ್ಯಪ್ ಡೇಟಾವನ್ನು ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡಬೇಕಾದ ಅಗತ್ಯವಿದೆ."</string>
     <string name="policylab_disableCamera" msgid="5749486347810162018">"ಕ್ಯಾಮರಾಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
     <string name="policydesc_disableCamera" msgid="3204405908799676104">"ಎಲ್ಲಾ ಸಾಧನ ಕ್ಯಾಮರಾಗಳ ಬಳಕೆಯನ್ನು ತಡೆಯಿರಿ."</string>
@@ -1103,7 +1103,7 @@
     <string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"ಈ ಪುಟದಲ್ಲಿಯೇ ಇರಿ"</string>
     <string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nನೀವು ಈ ಪುಟದಿಂದಾಚೆಗೆ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಲು ಖಚಿತವಾಗಿ ಬಯಸುವಿರಾ?"</string>
     <string name="autofill_window_title" msgid="4379134104008111961">"<xliff:g id="SERVICENAME">%1$s</xliff:g> ಸಹಾಯದಿಂದ ಸ್ವಯಂ-ಭರ್ತಿ"</string>
-    <string name="permlab_setAlarm" msgid="1158001610254173567">"ಅಲಾರಮ್ ಹೊಂದಿಸಿ"</string>
+    <string name="permlab_setAlarm" msgid="1158001610254173567">"ಅಲಾರಮ್ ಸೆಟ್ ಮಾಡಿ"</string>
     <string name="permdesc_setAlarm" msgid="2185033720060109640">"ಸ್ಥಾಪಿಸಲಾದ ಅಲಾರಮ್ ಗಡಿಯಾರ ಅಪ್ಲಿಕೇಶನ್‌ನಲ್ಲಿ ಅಲಾರಮ್ ಹೊಂದಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಕೆಲವು ಅಲಾರಮ್ ಗಡಿಯಾರ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಈ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸದಿರಬಹುದು."</string>
     <string name="permlab_addVoicemail" msgid="4770245808840814471">"ಧ್ವನಿಮೇಲ್ ಸೇರಿಸಿ"</string>
     <string name="permdesc_addVoicemail" msgid="5470312139820074324">"ನಿಮ್ಮ ದ್ವನಿಮೇಲ್‌ ಇನ್‌‌ಬಾಕ್ಸ್‌‌ಗೆ ಸಂದೇಶಗಳನ್ನು ಸೇರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
@@ -1158,38 +1158,22 @@
     <string name="duration_hours_shortest_future" msgid="2979276794547981674">"<xliff:g id="COUNT">%d</xliff:g>ಗಂ ಯಲ್ಲಿ"</string>
     <string name="duration_days_shortest_future" msgid="3392722163935571543">"<xliff:g id="COUNT">%d</xliff:g>ದಿ ದಲ್ಲಿ"</string>
     <string name="duration_years_shortest_future" msgid="5537464088352970388">"<xliff:g id="COUNT">%d</xliff:g>ವ ದಲ್ಲಿ"</string>
-    <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
-    <skip />
-    <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
-    <skip />
-    <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
-    <skip />
-    <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium (1465359726485910115) -->
-    <skip />
-    <!-- no translation found for duration_days_medium (5994225628248661388) -->
-    <skip />
-    <!-- no translation found for duration_years_medium (734023884353592526) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_past (893797065424596243) -->
-    <skip />
+    <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"<xliff:g id="COUNT">%d</xliff:g>ನಿಮಿಷದ ಹಿಂದೆ"</string>
+    <string name="duration_hours_shortest_past" msgid="2098397414186628489">"<xliff:g id="COUNT">%d</xliff:g>ಗಂಟೆ ಹಿಂದೆ"</string>
+    <string name="duration_days_shortest_past" msgid="1832006037955897625">"<xliff:g id="COUNT">%d</xliff:g>ದಿನಗಳ ಹಿಂದೆ"</string>
+    <string name="duration_years_shortest_past" msgid="6168256514200469291">"<xliff:g id="COUNT">%d</xliff:g>ವರ್ಷದ ಹಿಂದೆ"</string>
+    <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g>ನಿಮಿಷ"</string>
+    <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g>ಗಂಟೆ"</string>
+    <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g>ದಿನ"</string>
+    <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g>ವರ್ಷ"</string>
+    <string name="duration_minutes_medium_future" msgid="2750894988731934402">"<xliff:g id="COUNT">%d</xliff:g>ನಿಮಿಷದಲ್ಲಿ"</string>
+    <string name="duration_hours_medium_future" msgid="6050833881463849764">"<xliff:g id="COUNT">%d</xliff:g>ಗಂಟೆಯಲ್ಲಿ"</string>
+    <string name="duration_days_medium_future" msgid="1700821545602729963">"<xliff:g id="COUNT">%d</xliff:g>ದಿನದಲ್ಲಿ"</string>
+    <string name="duration_years_medium_future" msgid="3281018940397120166">"<xliff:g id="COUNT">%d</xliff:g>ವರ್ಷದಲ್ಲಿ"</string>
+    <string name="duration_minutes_medium_past" msgid="7400424340181947714">"<xliff:g id="COUNT">%d</xliff:g>ನಿಮಿಷದ ಹಿಂದೆ"</string>
+    <string name="duration_hours_medium_past" msgid="6709441336035202617">"<xliff:g id="COUNT">%d</xliff:g>ಗಂಟೆ ಹಿಂದೆ"</string>
+    <string name="duration_days_medium_past" msgid="5748156261134344532">"<xliff:g id="COUNT">%d</xliff:g>ದಿನಗಳ ಹಿಂದೆ"</string>
+    <string name="duration_years_medium_past" msgid="893797065424596243">"<xliff:g id="COUNT">%d</xliff:g>ವರ್ಷದ ಹಿಂದೆ"</string>
     <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# ನಿಮಿಷದ ಹಿಂದೆ}one{# ನಿಮಿಷಗಳ ಹಿಂದೆ}other{# ನಿಮಿಷಗಳ ಹಿಂದೆ}}"</string>
     <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# ಗಂಟೆಯ ಹಿಂದೆ}one{# ಗಂಟೆಗಳ ಹಿಂದೆ}other{# ಗಂಟೆಗಳ ಹಿಂದೆ}}"</string>
     <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# ದಿನದ ಹಿಂದೆ}one{# ದಿನಗಳ ಹಿಂದೆ}other{# ದಿನಗಳ ಹಿಂದೆ}}"</string>
@@ -1421,7 +1405,7 @@
     <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"ಆ್ಯಪ್‌ ಡೌನ್‌ಲೋಡ್ ಮಾಡಿ"</string>
     <string name="carrier_app_notification_title" msgid="5815477368072060250">"ಹೊಸ ಸಿಮ್ ಸೇರಿಸಲಾಗಿದೆ"</string>
     <string name="carrier_app_notification_text" msgid="6567057546341958637">"ಇದನ್ನು ಸ್ಥಾಪಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
-    <string name="time_picker_dialog_title" msgid="9053376764985220821">"ಸಮಯವನ್ನು ಹೊಂದಿಸಿ"</string>
+    <string name="time_picker_dialog_title" msgid="9053376764985220821">"ಸಮಯವನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
     <string name="date_picker_dialog_title" msgid="5030520449243071926">"ದಿನಾಂಕವನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
     <string name="date_time_set" msgid="4603445265164486816">"ಹೊಂದಿಸು"</string>
     <string name="date_time_done" msgid="8363155889402873463">"ಆಯಿತು"</string>
@@ -1622,7 +1606,7 @@
     <string name="time_picker_increment_hour_button" msgid="3063572723197178242">"ಗಂಟೆಯನ್ನು ಹೆಚ್ಚಿಸಿ"</string>
     <string name="time_picker_decrement_hour_button" msgid="584101766855054412">"ಗಂಟೆಯನ್ನು ಕಡಿಮೆ ಮಾಡಿ"</string>
     <string name="time_picker_increment_set_pm_button" msgid="5889149366900376419">"PM ಹೊಂದಿಸು"</string>
-    <string name="time_picker_decrement_set_am_button" msgid="1422608001541064087">"AM ಹೊಂದಿಸಿ"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="1422608001541064087">"AM ಸೆಟ್ ಮಾಡಿ"</string>
     <string name="date_picker_increment_month_button" msgid="3447263316096060309">"ತಿಂಗಳನ್ನು ಹೆಚ್ಚಿಸಿ"</string>
     <string name="date_picker_decrement_month_button" msgid="6531888937036883014">"ತಿಂಗಳು ಕಡಿಮೆಮಾಡಿ"</string>
     <string name="date_picker_increment_day_button" msgid="4349336637188534259">"ದಿನವನ್ನು ಹೆಚ್ಚಿಸಿ"</string>
@@ -2108,7 +2092,7 @@
     <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ"</string>
     <string name="time_picker_hour_label" msgid="4208590187662336864">"ಗಂಟೆ"</string>
     <string name="time_picker_minute_label" msgid="8307452311269824553">"ನಿಮಿಷ"</string>
-    <string name="time_picker_header_text" msgid="9073802285051516688">"ಸಮಯವನ್ನು ಹೊಂದಿಸಿ"</string>
+    <string name="time_picker_header_text" msgid="9073802285051516688">"ಸಮಯವನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
     <string name="time_picker_input_error" msgid="8386271930742451034">"ಮಾನ್ಯವಾದ ಸಮಯವನ್ನು ನಮೂದಿಸಿ"</string>
     <string name="time_picker_prompt_label" msgid="303588544656363889">"ಸಮಯ ಟೈಪ್ ಮಾಡಿ"</string>
     <string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"ಸಮಯವನ್ನು ನಮೂದಿಸಲು ಪಠ್ಯದ ನಮೂನೆಗೆ ಬದಲಿಸಿ."</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 1fea243..21925f8 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1158,38 +1158,22 @@
     <string name="duration_hours_shortest_future" msgid="2979276794547981674">"dalam <xliff:g id="COUNT">%d</xliff:g>j"</string>
     <string name="duration_days_shortest_future" msgid="3392722163935571543">"dalam <xliff:g id="COUNT">%d</xliff:g>h"</string>
     <string name="duration_years_shortest_future" msgid="5537464088352970388">"dalam <xliff:g id="COUNT">%d</xliff:g>t"</string>
-    <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
-    <skip />
-    <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
-    <skip />
-    <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
-    <skip />
-    <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium (1465359726485910115) -->
-    <skip />
-    <!-- no translation found for duration_days_medium (5994225628248661388) -->
-    <skip />
-    <!-- no translation found for duration_years_medium (734023884353592526) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_past (893797065424596243) -->
-    <skip />
+    <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"<xliff:g id="COUNT">%d</xliff:g>m yang lalu"</string>
+    <string name="duration_hours_shortest_past" msgid="2098397414186628489">"<xliff:g id="COUNT">%d</xliff:g>j yang lalu"</string>
+    <string name="duration_days_shortest_past" msgid="1832006037955897625">"<xliff:g id="COUNT">%d</xliff:g>h yang lalu"</string>
+    <string name="duration_years_shortest_past" msgid="6168256514200469291">"<xliff:g id="COUNT">%d</xliff:g>t yang lalu"</string>
+    <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g>min"</string>
+    <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g>jam"</string>
+    <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g>h"</string>
+    <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g>thn"</string>
+    <string name="duration_minutes_medium_future" msgid="2750894988731934402">"selepas <xliff:g id="COUNT">%d</xliff:g>minit"</string>
+    <string name="duration_hours_medium_future" msgid="6050833881463849764">"selepas <xliff:g id="COUNT">%d</xliff:g>jam"</string>
+    <string name="duration_days_medium_future" msgid="1700821545602729963">"dalam <xliff:g id="COUNT">%d</xliff:g>h"</string>
+    <string name="duration_years_medium_future" msgid="3281018940397120166">"selepas <xliff:g id="COUNT">%d</xliff:g>thn"</string>
+    <string name="duration_minutes_medium_past" msgid="7400424340181947714">"<xliff:g id="COUNT">%d</xliff:g>minit yang lalu"</string>
+    <string name="duration_hours_medium_past" msgid="6709441336035202617">"<xliff:g id="COUNT">%d</xliff:g>jam yang lalu"</string>
+    <string name="duration_days_medium_past" msgid="5748156261134344532">"<xliff:g id="COUNT">%d</xliff:g>h yang lalu"</string>
+    <string name="duration_years_medium_past" msgid="893797065424596243">"<xliff:g id="COUNT">%d</xliff:g>thn yang lalu"</string>
     <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# minit yang lalu}other{# minit yang lalu}}"</string>
     <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# jam yang lalu}other{# jam yang lalu}}"</string>
     <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# hari yang lalu}other{# hari yang lalu}}"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 8e943db..5ff383d 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1159,38 +1159,22 @@
     <string name="duration_hours_shortest_future" msgid="2979276794547981674">"em <xliff:g id="COUNT">%d</xliff:g>h"</string>
     <string name="duration_days_shortest_future" msgid="3392722163935571543">"em <xliff:g id="COUNT">%d</xliff:g> dias"</string>
     <string name="duration_years_shortest_future" msgid="5537464088352970388">"em <xliff:g id="COUNT">%d</xliff:g>a"</string>
-    <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
-    <skip />
-    <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
-    <skip />
-    <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
-    <skip />
-    <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium (1465359726485910115) -->
-    <skip />
-    <!-- no translation found for duration_days_medium (5994225628248661388) -->
-    <skip />
-    <!-- no translation found for duration_years_medium (734023884353592526) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_past (893797065424596243) -->
-    <skip />
+    <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"há <xliff:g id="COUNT">%d</xliff:g>min"</string>
+    <string name="duration_hours_shortest_past" msgid="2098397414186628489">"há <xliff:g id="COUNT">%d</xliff:g>h"</string>
+    <string name="duration_days_shortest_past" msgid="1832006037955897625">"há <xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_shortest_past" msgid="6168256514200469291">"há <xliff:g id="COUNT">%d</xliff:g> a"</string>
+    <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g>min"</string>
+    <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g>h"</string>
+    <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g> a"</string>
+    <string name="duration_minutes_medium_future" msgid="2750894988731934402">"em <xliff:g id="COUNT">%d</xliff:g>min"</string>
+    <string name="duration_hours_medium_future" msgid="6050833881463849764">"em <xliff:g id="COUNT">%d</xliff:g>h"</string>
+    <string name="duration_days_medium_future" msgid="1700821545602729963">"em <xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_medium_future" msgid="3281018940397120166">"em <xliff:g id="COUNT">%d</xliff:g> a"</string>
+    <string name="duration_minutes_medium_past" msgid="7400424340181947714">"há <xliff:g id="COUNT">%d</xliff:g>min"</string>
+    <string name="duration_hours_medium_past" msgid="6709441336035202617">"há <xliff:g id="COUNT">%d</xliff:g>h"</string>
+    <string name="duration_days_medium_past" msgid="5748156261134344532">"há <xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_medium_past" msgid="893797065424596243">"há <xliff:g id="COUNT">%d</xliff:g> a"</string>
     <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# minuto atrás}one{# minuto atrás}many{# minutos atrás}other{# minutos atrás}}"</string>
     <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# hora atrás}one{# hora atrás}many{# horas atrás}other{# horas atrás}}"</string>
     <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# dia atrás}one{# dia atrás}many{# dias atrás}other{# dias atrás}}"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index b5ee460..38a071a 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1159,38 +1159,22 @@
     <string name="duration_hours_shortest_future" msgid="2979276794547981674">"em <xliff:g id="COUNT">%d</xliff:g> h"</string>
     <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>
-    <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
-    <skip />
-    <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
-    <skip />
-    <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
-    <skip />
-    <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium (1465359726485910115) -->
-    <skip />
-    <!-- no translation found for duration_days_medium (5994225628248661388) -->
-    <skip />
-    <!-- no translation found for duration_years_medium (734023884353592526) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_past (893797065424596243) -->
-    <skip />
+    <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"há <xliff:g id="COUNT">%d</xliff:g> min"</string>
+    <string name="duration_hours_shortest_past" msgid="2098397414186628489">"há <xliff:g id="COUNT">%d</xliff:g> h"</string>
+    <string name="duration_days_shortest_past" msgid="1832006037955897625">"há <xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_shortest_past" msgid="6168256514200469291">"há <xliff:g id="COUNT">%d</xliff:g> ano(s)"</string>
+    <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g> min"</string>
+    <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g> h"</string>
+    <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g> ano(s)"</string>
+    <string name="duration_minutes_medium_future" msgid="2750894988731934402">"dentro de <xliff:g id="COUNT">%d</xliff:g> min"</string>
+    <string name="duration_hours_medium_future" msgid="6050833881463849764">"dentro de <xliff:g id="COUNT">%d</xliff:g> h"</string>
+    <string name="duration_days_medium_future" msgid="1700821545602729963">"dentro de <xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_medium_future" msgid="3281018940397120166">"dentro de <xliff:g id="COUNT">%d</xliff:g> ano(s)"</string>
+    <string name="duration_minutes_medium_past" msgid="7400424340181947714">"há <xliff:g id="COUNT">%d</xliff:g> min"</string>
+    <string name="duration_hours_medium_past" msgid="6709441336035202617">"há <xliff:g id="COUNT">%d</xliff:g> h"</string>
+    <string name="duration_days_medium_past" msgid="5748156261134344532">"há <xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_medium_past" msgid="893797065424596243">"há <xliff:g id="COUNT">%d</xliff:g> ano(s)"</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_days_relative" msgid="621965767567258302">"{count,plural, =1{Há # dia}many{Há # dias}other{Há # dias}}"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 8e943db..5ff383d 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1159,38 +1159,22 @@
     <string name="duration_hours_shortest_future" msgid="2979276794547981674">"em <xliff:g id="COUNT">%d</xliff:g>h"</string>
     <string name="duration_days_shortest_future" msgid="3392722163935571543">"em <xliff:g id="COUNT">%d</xliff:g> dias"</string>
     <string name="duration_years_shortest_future" msgid="5537464088352970388">"em <xliff:g id="COUNT">%d</xliff:g>a"</string>
-    <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
-    <skip />
-    <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
-    <skip />
-    <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
-    <skip />
-    <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium (1465359726485910115) -->
-    <skip />
-    <!-- no translation found for duration_days_medium (5994225628248661388) -->
-    <skip />
-    <!-- no translation found for duration_years_medium (734023884353592526) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_past (893797065424596243) -->
-    <skip />
+    <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"há <xliff:g id="COUNT">%d</xliff:g>min"</string>
+    <string name="duration_hours_shortest_past" msgid="2098397414186628489">"há <xliff:g id="COUNT">%d</xliff:g>h"</string>
+    <string name="duration_days_shortest_past" msgid="1832006037955897625">"há <xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_shortest_past" msgid="6168256514200469291">"há <xliff:g id="COUNT">%d</xliff:g> a"</string>
+    <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g>min"</string>
+    <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g>h"</string>
+    <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g> a"</string>
+    <string name="duration_minutes_medium_future" msgid="2750894988731934402">"em <xliff:g id="COUNT">%d</xliff:g>min"</string>
+    <string name="duration_hours_medium_future" msgid="6050833881463849764">"em <xliff:g id="COUNT">%d</xliff:g>h"</string>
+    <string name="duration_days_medium_future" msgid="1700821545602729963">"em <xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_medium_future" msgid="3281018940397120166">"em <xliff:g id="COUNT">%d</xliff:g> a"</string>
+    <string name="duration_minutes_medium_past" msgid="7400424340181947714">"há <xliff:g id="COUNT">%d</xliff:g>min"</string>
+    <string name="duration_hours_medium_past" msgid="6709441336035202617">"há <xliff:g id="COUNT">%d</xliff:g>h"</string>
+    <string name="duration_days_medium_past" msgid="5748156261134344532">"há <xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_medium_past" msgid="893797065424596243">"há <xliff:g id="COUNT">%d</xliff:g> a"</string>
     <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# minuto atrás}one{# minuto atrás}many{# minutos atrás}other{# minutos atrás}}"</string>
     <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# hora atrás}one{# hora atrás}many{# horas atrás}other{# horas atrás}}"</string>
     <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# dia atrás}one{# dia atrás}many{# dias atrás}other{# dias atrás}}"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index dc61496..e7e96f5 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1160,38 +1160,22 @@
     <string name="duration_hours_shortest_future" msgid="2979276794547981674">"čez <xliff:g id="COUNT">%d</xliff:g> h"</string>
     <string name="duration_days_shortest_future" msgid="3392722163935571543">"čez <xliff:g id="COUNT">%d</xliff:g> d"</string>
     <string name="duration_years_shortest_future" msgid="5537464088352970388">"čez <xliff:g id="COUNT">%d</xliff:g> l"</string>
-    <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
-    <skip />
-    <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
-    <skip />
-    <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
-    <skip />
-    <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium (1465359726485910115) -->
-    <skip />
-    <!-- no translation found for duration_days_medium (5994225628248661388) -->
-    <skip />
-    <!-- no translation found for duration_years_medium (734023884353592526) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_past (893797065424596243) -->
-    <skip />
+    <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"pred <xliff:g id="COUNT">%d</xliff:g> min"</string>
+    <string name="duration_hours_shortest_past" msgid="2098397414186628489">"pred <xliff:g id="COUNT">%d</xliff:g> h"</string>
+    <string name="duration_days_shortest_past" msgid="1832006037955897625">"pred <xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_shortest_past" msgid="6168256514200469291">"pred <xliff:g id="COUNT">%d</xliff:g> l"</string>
+    <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g> min"</string>
+    <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g> h"</string>
+    <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g> l"</string>
+    <string name="duration_minutes_medium_future" msgid="2750894988731934402">"čez <xliff:g id="COUNT">%d</xliff:g> min"</string>
+    <string name="duration_hours_medium_future" msgid="6050833881463849764">"čez <xliff:g id="COUNT">%d</xliff:g> h"</string>
+    <string name="duration_days_medium_future" msgid="1700821545602729963">"čez <xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_medium_future" msgid="3281018940397120166">"čez <xliff:g id="COUNT">%d</xliff:g> l"</string>
+    <string name="duration_minutes_medium_past" msgid="7400424340181947714">"pred <xliff:g id="COUNT">%d</xliff:g> min"</string>
+    <string name="duration_hours_medium_past" msgid="6709441336035202617">"pred <xliff:g id="COUNT">%d</xliff:g> h"</string>
+    <string name="duration_days_medium_past" msgid="5748156261134344532">"pred <xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_medium_past" msgid="893797065424596243">"pred <xliff:g id="COUNT">%d</xliff:g> l"</string>
     <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{Pred # minuto}one{Pred # minuto}two{Pred # minutama}few{Pred # minutami}other{Pred # minutami}}"</string>
     <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{Pred # uro}one{Pred # uro}two{Pred # urama}few{Pred # urami}other{Pred # urami}}"</string>
     <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{Pred # dnevom}one{Pred # dnevom}two{Pred # dnevoma}few{Pred # dnevi}other{Pred # dnevi}}"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index a7207ac..4b22b7d 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1158,38 +1158,22 @@
     <string name="duration_hours_shortest_future" msgid="2979276794547981674">"om <xliff:g id="COUNT">%d</xliff:g> tim"</string>
     <string name="duration_days_shortest_future" msgid="3392722163935571543">"om <xliff:g id="COUNT">%d</xliff:g> d"</string>
     <string name="duration_years_shortest_future" msgid="5537464088352970388">"om <xliff:g id="COUNT">%d</xliff:g> år"</string>
-    <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
-    <skip />
-    <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
-    <skip />
-    <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
-    <skip />
-    <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium (1465359726485910115) -->
-    <skip />
-    <!-- no translation found for duration_days_medium (5994225628248661388) -->
-    <skip />
-    <!-- no translation found for duration_years_medium (734023884353592526) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_past (893797065424596243) -->
-    <skip />
+    <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"för <xliff:g id="COUNT">%d</xliff:g> m sedan"</string>
+    <string name="duration_hours_shortest_past" msgid="2098397414186628489">"för <xliff:g id="COUNT">%d</xliff:g> h sedan"</string>
+    <string name="duration_days_shortest_past" msgid="1832006037955897625">"för <xliff:g id="COUNT">%d</xliff:g> d sedan"</string>
+    <string name="duration_years_shortest_past" msgid="6168256514200469291">"för <xliff:g id="COUNT">%d</xliff:g> år sedan"</string>
+    <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g> min"</string>
+    <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g> h"</string>
+    <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g> år"</string>
+    <string name="duration_minutes_medium_future" msgid="2750894988731934402">"om <xliff:g id="COUNT">%d</xliff:g> min"</string>
+    <string name="duration_hours_medium_future" msgid="6050833881463849764">"om <xliff:g id="COUNT">%d</xliff:g> h"</string>
+    <string name="duration_days_medium_future" msgid="1700821545602729963">"om <xliff:g id="COUNT">%d</xliff:g> d"</string>
+    <string name="duration_years_medium_future" msgid="3281018940397120166">"om <xliff:g id="COUNT">%d</xliff:g> år"</string>
+    <string name="duration_minutes_medium_past" msgid="7400424340181947714">"för <xliff:g id="COUNT">%d</xliff:g> min sedan"</string>
+    <string name="duration_hours_medium_past" msgid="6709441336035202617">"för <xliff:g id="COUNT">%d</xliff:g> h sedan"</string>
+    <string name="duration_days_medium_past" msgid="5748156261134344532">"för <xliff:g id="COUNT">%d</xliff:g> d sedan"</string>
+    <string name="duration_years_medium_past" msgid="893797065424596243">"för <xliff:g id="COUNT">%d</xliff:g> år sedan"</string>
     <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{För # minut sedan}other{För # minuter sedan}}"</string>
     <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{För # timme sedan}other{För # timmar sedan}}"</string>
     <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{För # dag sedan}other{För # dagar sedan}}"</string>
diff --git a/core/res/res/values-sw600dp/config.xml b/core/res/res/values-sw600dp/config.xml
index 34b6a54..0b0a4cb 100644
--- a/core/res/res/values-sw600dp/config.xml
+++ b/core/res/res/values-sw600dp/config.xml
@@ -47,7 +47,7 @@
     <bool name="config_navBarCanMove">false</bool>
 
     <!-- Set to true to enable the user switcher on the keyguard. -->
-    <bool name="config_keyguardUserSwitcher">true</bool>
+    <bool name="config_keyguardUserSwitcher">false</bool>
 
     <!-- If true, show multiuser switcher by default unless the user specifically disables it. -->
     <bool name="config_showUserSwitcherByDefault">true</bool>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 28f06ab..89e2e68 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1158,38 +1158,22 @@
     <string name="duration_hours_shortest_future" msgid="2979276794547981674">"<xliff:g id="COUNT">%d</xliff:g> soatdan keyin"</string>
     <string name="duration_days_shortest_future" msgid="3392722163935571543">"<xliff:g id="COUNT">%d</xliff:g> kundan keyin"</string>
     <string name="duration_years_shortest_future" msgid="5537464088352970388">"<xliff:g id="COUNT">%d</xliff:g> yildan keyin"</string>
-    <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
-    <skip />
-    <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
-    <skip />
-    <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
-    <skip />
-    <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium (1465359726485910115) -->
-    <skip />
-    <!-- no translation found for duration_days_medium (5994225628248661388) -->
-    <skip />
-    <!-- no translation found for duration_years_medium (734023884353592526) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
-    <skip />
-    <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
-    <skip />
-    <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
-    <skip />
-    <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
-    <skip />
-    <!-- no translation found for duration_years_medium_past (893797065424596243) -->
-    <skip />
+    <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"<xliff:g id="COUNT">%d</xliff:g> daq oldin"</string>
+    <string name="duration_hours_shortest_past" msgid="2098397414186628489">"<xliff:g id="COUNT">%d</xliff:g> soat oldin"</string>
+    <string name="duration_days_shortest_past" msgid="1832006037955897625">"<xliff:g id="COUNT">%d</xliff:g> kun oldin"</string>
+    <string name="duration_years_shortest_past" msgid="6168256514200469291">"<xliff:g id="COUNT">%d</xliff:g> yil oldin"</string>
+    <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g>daq"</string>
+    <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g>st"</string>
+    <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> k"</string>
+    <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g>yil"</string>
+    <string name="duration_minutes_medium_future" msgid="2750894988731934402">"<xliff:g id="COUNT">%d</xliff:g> daqiqadan keyin"</string>
+    <string name="duration_hours_medium_future" msgid="6050833881463849764">"<xliff:g id="COUNT">%d</xliff:g> soatdan keyin"</string>
+    <string name="duration_days_medium_future" msgid="1700821545602729963">"<xliff:g id="COUNT">%d</xliff:g> kundan keyin"</string>
+    <string name="duration_years_medium_future" msgid="3281018940397120166">"<xliff:g id="COUNT">%d</xliff:g> yildan keyin"</string>
+    <string name="duration_minutes_medium_past" msgid="7400424340181947714">"<xliff:g id="COUNT">%d</xliff:g> daqiqa oldin"</string>
+    <string name="duration_hours_medium_past" msgid="6709441336035202617">"<xliff:g id="COUNT">%d</xliff:g> soat oldin"</string>
+    <string name="duration_days_medium_past" msgid="5748156261134344532">"<xliff:g id="COUNT">%d</xliff:g> kun oldin"</string>
+    <string name="duration_years_medium_past" msgid="893797065424596243">"<xliff:g id="COUNT">%d</xliff:g> yil oldin"</string>
     <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# daqiqa oldin}other{# daqiqa oldin}}"</string>
     <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# soat oldin}other{# soat oldin}}"</string>
     <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# kun oldin}other{# kun oldin}}"</string>
diff --git a/core/res/res/values-w192dp/dimens_material.xml b/core/res/res/values-w192dp/dimens_material.xml
index 797bf5a..a11eb7f 100644
--- a/core/res/res/values-w192dp/dimens_material.xml
+++ b/core/res/res/values-w192dp/dimens_material.xml
@@ -14,7 +14,11 @@
      limitations under the License.
 -->
 <resources>
+    <dimen name="screen_percentage_0416">7.99dp</dimen>
     <dimen name="screen_percentage_05">9.6dp</dimen>
+    <dimen name="screen_percentage_052">9.98dp</dimen>
     <dimen name="screen_percentage_10">19.2dp</dimen>
+    <dimen name="screen_percentage_12">23.04dp</dimen>
     <dimen name="screen_percentage_15">28.8dp</dimen>
+    <dimen name="screen_percentage_3646">69.99dp</dimen>
 </resources>
diff --git a/core/res/res/values-w195dp/dimens_material.xml b/core/res/res/values-w195dp/dimens_material.xml
index 7f3ad29..346066f 100644
--- a/core/res/res/values-w195dp/dimens_material.xml
+++ b/core/res/res/values-w195dp/dimens_material.xml
@@ -14,7 +14,11 @@
      limitations under the License.
 -->
 <resources>
+    <dimen name="screen_percentage_0416">8.11dp</dimen>
     <dimen name="screen_percentage_05">9.75dp</dimen>
+    <dimen name="screen_percentage_052">10.14dp</dimen>
     <dimen name="screen_percentage_10">19.5dp</dimen>
+    <dimen name="screen_percentage_12">23.4dp</dimen>
     <dimen name="screen_percentage_15">29.25dp</dimen>
+    <dimen name="screen_percentage_3646">71.09dp</dimen>
 </resources>
diff --git a/core/res/res/values-w198dp/dimens_material.xml b/core/res/res/values-w198dp/dimens_material.xml
index a8aed25..4c88f05 100644
--- a/core/res/res/values-w198dp/dimens_material.xml
+++ b/core/res/res/values-w198dp/dimens_material.xml
@@ -14,7 +14,11 @@
      limitations under the License.
 -->
 <resources>
+    <dimen name="screen_percentage_0416">8.24dp</dimen>
     <dimen name="screen_percentage_05">9.9dp</dimen>
+    <dimen name="screen_percentage_052">10.3dp</dimen>
     <dimen name="screen_percentage_10">19.8dp</dimen>
+    <dimen name="screen_percentage_12">23.76dp</dimen>
     <dimen name="screen_percentage_15">29.7dp</dimen>
+    <dimen name="screen_percentage_3646">72.1dp</dimen>
 </resources>
diff --git a/core/res/res/values-w204dp-round-watch/dimens_material.xml b/core/res/res/values-w204dp-round-watch/dimens_material.xml
index c07d5c4..54bb0c9 100644
--- a/core/res/res/values-w204dp-round-watch/dimens_material.xml
+++ b/core/res/res/values-w204dp-round-watch/dimens_material.xml
@@ -14,7 +14,11 @@
      limitations under the License.
 -->
 <resources>
+    <dimen name="screen_percentage_0416">8.48dp</dimen>
     <dimen name="screen_percentage_05">10.2dp</dimen>
+    <dimen name="screen_percentage_052">10.61dp</dimen>
     <dimen name="screen_percentage_10">20.4dp</dimen>
+    <dimen name="screen_percentage_12">24.48dp</dimen>
     <dimen name="screen_percentage_15">30.6dp</dimen>
+    <dimen name="screen_percentage_3646">74.42dp</dimen>
 </resources>
diff --git a/core/res/res/values-w205dp/dimens_material.xml b/core/res/res/values-w205dp/dimens_material.xml
index 94907ee..60f65bb 100644
--- a/core/res/res/values-w205dp/dimens_material.xml
+++ b/core/res/res/values-w205dp/dimens_material.xml
@@ -14,7 +14,11 @@
      limitations under the License.
 -->
 <resources>
+    <dimen name="screen_percentage_0416">8.52dp</dimen>
     <dimen name="screen_percentage_05">10.25dp</dimen>
+    <dimen name="screen_percentage_052">10.66dp</dimen>
     <dimen name="screen_percentage_10">20.5dp</dimen>
+    <dimen name="screen_percentage_12">24.6dp</dimen>
     <dimen name="screen_percentage_15">30.75dp</dimen>
+    <dimen name="screen_percentage_3646">74.78dp</dimen>
 </resources>
diff --git a/core/res/res/values-w208dp/dimens_material.xml b/core/res/res/values-w208dp/dimens_material.xml
index 069eeb0..7f4ccd9 100644
--- a/core/res/res/values-w208dp/dimens_material.xml
+++ b/core/res/res/values-w208dp/dimens_material.xml
@@ -14,7 +14,11 @@
      limitations under the License.
 -->
 <resources>
+    <dimen name="screen_percentage_0416">8.65dp</dimen>
     <dimen name="screen_percentage_05">10.4dp</dimen>
+    <dimen name="screen_percentage_052">10.82dp</dimen>
     <dimen name="screen_percentage_10">20.8dp</dimen>
+    <dimen name="screen_percentage_12">24.96dp</dimen>
     <dimen name="screen_percentage_15">31.2dp</dimen>
+    <dimen name="screen_percentage_3646">75.65dp</dimen>
 </resources>
diff --git a/core/res/res/values-w210dp-round-watch/dimens_material.xml b/core/res/res/values-w210dp-round-watch/dimens_material.xml
index 79acf84..ca0889e 100644
--- a/core/res/res/values-w210dp-round-watch/dimens_material.xml
+++ b/core/res/res/values-w210dp-round-watch/dimens_material.xml
@@ -14,6 +14,14 @@
      limitations under the License.
 -->
 <resources>
+    <dimen name="screen_percentage_0416">8.73dp</dimen>
+    <dimen name="screen_percentage_05">10.5dp</dimen>
+    <dimen name="screen_percentage_052">10.92dp</dimen>
+    <dimen name="screen_percentage_10">21dp</dimen>
+    <dimen name="screen_percentage_12">25.2dp</dimen>
+    <dimen name="screen_percentage_15">31.5dp</dimen>
+    <dimen name="screen_percentage_3646">76.57dp</dimen>
+
     <dimen name="text_size_display_4_material">80sp</dimen>
     <dimen name="text_size_display_3_material">50sp</dimen>
     <dimen name="text_size_display_2_material">40sp</dimen>
diff --git a/core/res/res/values-w211dp/dimens_material.xml b/core/res/res/values-w211dp/dimens_material.xml
index bd7ca9a..c483e45 100644
--- a/core/res/res/values-w211dp/dimens_material.xml
+++ b/core/res/res/values-w211dp/dimens_material.xml
@@ -14,7 +14,11 @@
      limitations under the License.
 -->
 <resources>
+    <dimen name="screen_percentage_0416">8.77dp</dimen>
     <dimen name="screen_percentage_05">10.55dp</dimen>
+    <dimen name="screen_percentage_052">10.97dp</dimen>
     <dimen name="screen_percentage_10">21.1dp</dimen>
+    <dimen name="screen_percentage_12">25.32dp</dimen>
     <dimen name="screen_percentage_15">31.65dp</dimen>
+    <dimen name="screen_percentage_3646">76.93dp</dimen>
 </resources>
diff --git a/core/res/res/values-w213dp/dimens_material.xml b/core/res/res/values-w213dp/dimens_material.xml
index 8a4e3a0..093c298 100644
--- a/core/res/res/values-w213dp/dimens_material.xml
+++ b/core/res/res/values-w213dp/dimens_material.xml
@@ -14,7 +14,11 @@
      limitations under the License.
 -->
 <resources>
+    <dimen name="screen_percentage_0416">8.85dp</dimen>
     <dimen name="screen_percentage_05">10.65dp</dimen>
+    <dimen name="screen_percentage_052">11.07dp</dimen>
     <dimen name="screen_percentage_10">21.3dp</dimen>
+    <dimen name="screen_percentage_12">25.56dp</dimen>
     <dimen name="screen_percentage_15">31.95dp</dimen>
+    <dimen name="screen_percentage_3646">77.66dp</dimen>
 </resources>
diff --git a/core/res/res/values-w216dp/dimens_material.xml b/core/res/res/values-w216dp/dimens_material.xml
new file mode 100644
index 0000000..71dbf72
--- /dev/null
+++ b/core/res/res/values-w216dp/dimens_material.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.
+-->
+<resources>
+    <dimen name="screen_percentage_0416">8.99dp</dimen>
+    <dimen name="screen_percentage_05">10.8dp</dimen>
+    <dimen name="screen_percentage_052">11.23dp</dimen>
+    <dimen name="screen_percentage_10">21.6dp</dimen>
+    <dimen name="screen_percentage_12">25.92dp</dimen>
+    <dimen name="screen_percentage_15">32.4dp</dimen>
+    <dimen name="screen_percentage_3646">78.77dp</dimen>
+</resources>
diff --git a/core/res/res/values-w225dp/dimens_material.xml b/core/res/res/values-w225dp/dimens_material.xml
index aa822a3..6df34a5 100644
--- a/core/res/res/values-w225dp/dimens_material.xml
+++ b/core/res/res/values-w225dp/dimens_material.xml
@@ -14,7 +14,11 @@
      limitations under the License.
 -->
 <resources>
+    <dimen name="screen_percentage_0416">9.36dp</dimen>
     <dimen name="screen_percentage_05">11.25dp</dimen>
+    <dimen name="screen_percentage_052">11.7dp</dimen>
     <dimen name="screen_percentage_10">22.5dp</dimen>
+    <dimen name="screen_percentage_12">27dp</dimen>
     <dimen name="screen_percentage_15">33.75dp</dimen>
+    <dimen name="screen_percentage_3646">82.46dp</dimen>
 </resources>
diff --git a/core/res/res/values-w227dp/dimens_material.xml b/core/res/res/values-w227dp/dimens_material.xml
index eb4df8a2..bbf4924 100644
--- a/core/res/res/values-w227dp/dimens_material.xml
+++ b/core/res/res/values-w227dp/dimens_material.xml
@@ -14,7 +14,11 @@
      limitations under the License.
 -->
 <resources>
+    <dimen name="screen_percentage_0416">9.44dp</dimen>
     <dimen name="screen_percentage_05">11.35dp</dimen>
+    <dimen name="screen_percentage_052">11.8dp</dimen>
     <dimen name="screen_percentage_10">22.7dp</dimen>
+    <dimen name="screen_percentage_12">27.24dp</dimen>
     <dimen name="screen_percentage_15">34.05dp</dimen>
+    <dimen name="screen_percentage_3646">83.19dp</dimen>
 </resources>
diff --git a/core/res/res/values-w228dp/dimens_material.xml b/core/res/res/values-w228dp/dimens_material.xml
index a200975..24bbb4c 100644
--- a/core/res/res/values-w228dp/dimens_material.xml
+++ b/core/res/res/values-w228dp/dimens_material.xml
@@ -14,7 +14,11 @@
      limitations under the License.
 -->
 <resources>
+    <dimen name="screen_percentage_0416">9.48dp</dimen>
     <dimen name="screen_percentage_05">11.4dp</dimen>
+    <dimen name="screen_percentage_052">11.86dp</dimen>
     <dimen name="screen_percentage_10">22.8dp</dimen>
+    <dimen name="screen_percentage_12">27.36dp</dimen>
     <dimen name="screen_percentage_15">34.2dp</dimen>
+    <dimen name="screen_percentage_3646">83.55dp</dimen>
 </resources>
diff --git a/core/res/res/values-w240dp/dimens_material.xml b/core/res/res/values-w240dp/dimens_material.xml
index a4b58fa9..bd26c8b 100644
--- a/core/res/res/values-w240dp/dimens_material.xml
+++ b/core/res/res/values-w240dp/dimens_material.xml
@@ -14,7 +14,11 @@
      limitations under the License.
 -->
 <resources>
+    <dimen name="screen_percentage_0416">9.98dp</dimen>
     <dimen name="screen_percentage_05">12dp</dimen>
+    <dimen name="screen_percentage_052">12.48dp</dimen>
     <dimen name="screen_percentage_10">24dp</dimen>
+    <dimen name="screen_percentage_12">28.8dp</dimen>
     <dimen name="screen_percentage_15">36dp</dimen>
+    <dimen name="screen_percentage_3646">87.5dp</dimen>
 </resources>
diff --git a/core/res/res/values-watch-v36/colors.xml b/core/res/res/values-watch-v36/colors.xml
deleted file mode 100644
index 4bc2a66..0000000
--- a/core/res/res/values-watch-v36/colors.xml
+++ /dev/null
@@ -1,18 +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.
-  -->
-<!-- TODO(b/372524566): update color token's value to match material3 design. -->
-<resources>
-</resources>
\ No newline at end of file
diff --git a/core/res/res/values-watch-v36/dimens_material.xml b/core/res/res/values-watch-v36/dimens_material.xml
deleted file mode 100644
index 7232786..0000000
--- a/core/res/res/values-watch-v36/dimens_material.xml
+++ /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.
-  -->
-<resources>
-    <!-- values for material3 button -->
-    <dimen name="btn_material_width">172dp</dimen>
-    <dimen name="btn_material_height">52dp</dimen>
-    <dimen name="btn_horizontal_edge_padding">14dp</dimen>
-    <dimen name="btn_drawable_padding">6dp</dimen>
-    <dimen name="btn_lineHeight">18sp</dimen>
-    <dimen name="btn_textSize">15sp</dimen>
-
-    <!-- values for material3 AlertDialog -->
-    <dimen name="dialog_btn_negative_width">60dp</dimen>
-    <dimen name="dialog_btn_negative_height">60dp</dimen>
-    <dimen name="dialog_btn_confirm_width">62dp</dimen>
-    <dimen name="dialog_btn_confirm_height">60dp</dimen>
-
-    <!-- Opacity factor for disabled material3 widget -->
-    <dimen name="disabled_alpha_device_default">0.12</dimen>
-    <dimen name="primary_content_alpha_device_default">0.38</dimen>
-
-    <!--  values for material3 progress bar(progress indicator)  -->
-    <item name="progressbar_inner_radius_ratio" format="float" type="dimen">2.12</item>
-    <dimen name="progressbar_thickness">8dp</dimen>
-    <dimen name="progressbar_elevation">0.1dp</dimen>
-</resources>
diff --git a/core/res/res/values-watch-v36/styles_material.xml b/core/res/res/values-watch-v36/styles_material.xml
deleted file mode 100644
index 6e5ef68..0000000
--- a/core/res/res/values-watch-v36/styles_material.xml
+++ /dev/null
@@ -1,105 +0,0 @@
-<?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>
-    <!--  Button Styles  -->
-    <!-- Material Button - Filled (primary colored) -->
-    <style name="Widget.DeviceDefault.Button.Filled" parent="Widget.DeviceDefault.Button.WearMaterial3">
-        <item name="android:background">@drawable/btn_background_material_filled</item>
-        <item name="textAppearance">@style/TextAppearance.Widget.Button.Material.Filled</item>
-    </style>
-
-    <!-- Material Button - Filled Tonal (Override system default button styles) -->
-    <style name="Widget.DeviceDefault.Button.WearMaterial3">
-        <item name="background">@drawable/btn_background_material_filled_tonal</item>
-        <item name="textAppearance">@style/TextAppearance.Widget.Button.Material</item>
-        <item name="minHeight">@dimen/btn_material_height</item>
-        <item name="maxWidth">@dimen/btn_material_width</item>
-        <item name="android:paddingStart">@dimen/btn_horizontal_edge_padding</item>
-        <item name="android:paddingEnd">@dimen/btn_horizontal_edge_padding</item>
-        <item name="android:drawablePadding">@dimen/btn_drawable_padding</item>
-        <item name="android:maxLines">2</item>
-        <item name="android:ellipsize">end</item>
-        <item name="android:breakStrategy">simple</item>
-        <item name="stateListAnimator">@anim/button_state_list_anim_material</item>
-        <item name="focusable">true</item>
-        <item name="clickable">true</item>
-        <item name="gravity">center_vertical</item>
-    </style>
-
-    <!-- Material Button - Outlined -->
-    <style name="Widget.DeviceDefault.Button.Outlined" parent="Widget.DeviceDefault.Button.WearMaterial3">
-        <item name="android:background">@drawable/btn_background_material_outlined</item>
-    </style>
-
-    <!-- Material Button - Text -->
-    <style name="Widget.DeviceDefault.Button.Text" parent="Widget.DeviceDefault.Button.WearMaterial3">
-        <item name="android:background">@drawable/btn_background_material_text</item>
-    </style>
-
-    <!--  Text Styles  -->
-    <!-- TextAppearance for Material Button - Filled  -->
-    <style name="TextAppearance.Widget.Button.Material.Filled">
-        <item name="textColor">@color/btn_material_filled_content_color</item>
-    </style>
-
-    <!-- TextAppearance for Material Button - Filled Tonal  -->
-    <style name="TextAppearance.Widget.Button.Material" parent="TextAppearance.DeviceDefault">
-        <item name="android:fontFamily">font-family-flex-device-default</item>
-        <item name="android:fontVariationSettings">"'wdth' 90, 'wght' 500, 'ROND' 100, 'opsz' 15, 'GRAD' 0"</item>
-        <item name="textSize">@dimen/btn_textSize</item>
-        <item name="textColor">@color/btn_material_filled_tonal_content_color</item>
-        <item name="lineHeight">@dimen/btn_lineHeight</item>
-    </style>
-
-    <!--  AlertDialog Styles  -->
-    <style name="AlertDialog.DeviceDefault.WearMaterial3">
-        <item name="layout">@layout/alert_dialog_wear_material3</item>
-    </style>
-
-    <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3" parent="Widget.DeviceDefault.Button">
-        <item name="android:textSize">0sp</item>
-        <item name="android:gravity">center</item>
-        <item name="android:paddingStart">0dp</item>
-        <item name="android:paddingEnd">0dp</item>
-        <item name="android:drawablePadding">0dp</item>
-    </style>
-
-    <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3.Confirm">
-        <!-- Use a ImageView as background -->
-        <item name="background">@android:color/transparent</item>
-        <item name="minWidth">@dimen/dialog_btn_confirm_width</item>
-        <item name="minHeight">@dimen/dialog_btn_confirm_height</item>
-    </style>
-
-    <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3.Negative">
-        <item name="background">@drawable/dialog_alert_button_negative</item>
-        <item name="minWidth">@dimen/dialog_btn_negative_width</item>
-        <item name="minHeight">@dimen/dialog_btn_negative_height</item>
-        <item name="maxWidth">@dimen/dialog_btn_negative_width</item>
-        <item name="maxHeight">@dimen/dialog_btn_negative_height</item>
-    </style>
-
-    <!-- Wear Material3 Progress Bar style: progressed ring.-->
-    <style name="Widget.DeviceDefault.ProgressBar.WearMaterial3">
-        <item name="indeterminateOnly">false</item>
-        <item name="progressDrawable">@drawable/progress_ring_wear_material3</item>
-        <item name="minHeight">@dimen/progress_bar_height</item>
-        <item name="maxHeight">@dimen/progress_bar_height</item>
-        <item name="mirrorForRtl">true</item>
-    </style>
-</resources>
\ No newline at end of file
diff --git a/core/res/res/values-watch/styles_device_default.xml b/core/res/res/values-watch/styles_device_default.xml
deleted file mode 100644
index 8a2ce5d..0000000
--- a/core/res/res/values-watch/styles_device_default.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<resources>
-    <style name="DialogWindowTitle.DeviceDefault" parent="DialogWindowTitle.Material">
-      <item name="maxLines">2</item>
-      <item name="shadowRadius">0</item>
-      <item name="ellipsize">end</item>
-      <item name="textAppearance">@style/TextAppearance.DeviceDefault.Title</item>
-    </style>
-    <style name="TextAppearance.DeviceDefault.Body1" parent="TextAppearance.Material.Body1">
-        <item name="android:textSize">15sp</item>
-        <item name="android:fontFamily">sans-serif</item>
-    </style>
-    <style name="TextAppearance.DeviceDefault.Title" parent="TextAppearance.Material.Title">
-        <item name="android:textSize">16sp</item>
-        <item name="android:fontFamily">google-sans</item>
-        <item name="android:textStyle">bold</item>
-    </style>
-    <style name="TextAppearance.DeviceDefault.Subhead" parent="TextAppearance.Material.Subhead">
-        <item name="android:textSize">16sp</item>
-        <item name="android:fontFamily">google-sans-medium</item>
-    </style>
-    <style name="BaseErrorDialog.DeviceDefault" parent="AlertDialog.DeviceDefault">
-        <item name="layout">@layout/watch_base_error_dialog</item>
-    </style>
-</resources>
diff --git a/core/res/res/values-watch/styles_device_defaults.xml b/core/res/res/values-watch/styles_device_defaults.xml
new file mode 100644
index 0000000..f3c85a9
--- /dev/null
+++ b/core/res/res/values-watch/styles_device_defaults.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+    <style name="DialogWindowTitle.DeviceDefault" parent="DialogWindowTitle.Material">
+        <item name="maxLines">2</item>
+        <item name="shadowRadius">0</item>
+        <item name="ellipsize">end</item>
+        <item name="textAppearance">@style/TextAppearance.DeviceDefault.Title</item>
+    </style>
+    <style name="TextAppearance.DeviceDefault.Body1" parent="TextAppearance.Material.Body1">
+        <item name="android:textSize">15sp</item>
+        <item name="android:fontFamily">sans-serif</item>
+    </style>
+    <style name="TextAppearance.DeviceDefault.Title" parent="TextAppearance.Material.Title">
+        <item name="android:textSize">16sp</item>
+        <item name="android:fontFamily">google-sans</item>
+        <item name="android:textStyle">bold</item>
+    </style>
+    <style name="TextAppearance.DeviceDefault.Subhead" parent="TextAppearance.Material.Subhead">
+        <item name="android:textSize">16sp</item>
+        <item name="android:fontFamily">google-sans-medium</item>
+    </style>
+    <style name="BaseErrorDialog.DeviceDefault" parent="AlertDialog.DeviceDefault">
+        <item name="layout">@layout/watch_base_error_dialog</item>
+    </style>
+
+    <!--  Button Styles  -->
+    <!-- Material Button - Filled (primary colored) -->
+    <style name="Widget.DeviceDefault.Button.Filled" parent="Widget.DeviceDefault.Button.WearMaterial3">
+        <item name="android:background">@drawable/btn_background_material_filled_watch</item>
+        <item name="textAppearance">@style/TextAppearance.Widget.Button.Material.Filled</item>
+    </style>
+
+    <!-- Material Button - Filled Tonal (Override system default button styles) -->
+    <style name="Widget.DeviceDefault.Button.WearMaterial3">
+        <item name="background">@drawable/btn_background_material_filled_tonal_watch</item>
+        <item name="textAppearance">@style/TextAppearance.Widget.Button.Material</item>
+        <item name="minHeight">@dimen/btn_material_height</item>
+        <item name="maxWidth">@dimen/btn_material_width</item>
+        <item name="android:paddingStart">@dimen/btn_horizontal_edge_padding</item>
+        <item name="android:paddingEnd">@dimen/btn_horizontal_edge_padding</item>
+        <item name="android:drawablePadding">@dimen/btn_drawable_padding</item>
+        <item name="android:maxLines">2</item>
+        <item name="android:ellipsize">end</item>
+        <item name="android:breakStrategy">simple</item>
+        <item name="stateListAnimator">@anim/button_state_list_anim_material</item>
+        <item name="focusable">true</item>
+        <item name="clickable">true</item>
+        <item name="gravity">center_vertical</item>
+    </style>
+
+    <!-- Wear Material3 Button - Outlined -->
+    <style name="Widget.DeviceDefault.Button.Outlined" parent="Widget.DeviceDefault.Button.WearMaterial3">
+        <item name="android:background">@drawable/btn_background_material_outlined_watch</item>
+    </style>
+
+    <!-- Wear Material3 Button - Text -->
+    <style name="Widget.DeviceDefault.Button.Text" parent="Widget.DeviceDefault.Button.WearMaterial3">
+        <item name="android:background">@drawable/btn_background_material_text_watch</item>
+    </style>
+
+    <!--  Wear Material3 AlertDialog Styles  -->
+    <style name="AlertDialog.DeviceDefault.WearMaterial3">
+        <item name="layout">@layout/alert_dialog_watch</item>
+    </style>
+
+    <!-- Wear Material3 Progress Bar style: progressed ring.-->
+    <style name="Widget.DeviceDefault.ProgressBar.WearMaterial3">
+        <item name="indeterminateOnly">false</item>
+        <item name="progressDrawable">@drawable/progress_ring_watch</item>
+        <item name="minHeight">@dimen/progress_bar_height</item>
+        <item name="maxHeight">@dimen/progress_bar_height</item>
+        <item name="mirrorForRtl">true</item>
+    </style>
+</resources>
diff --git a/core/res/res/values-watch/themes_device_defaults.xml b/core/res/res/values-watch/themes_device_defaults.xml
index 7ac1759..60aec53 100644
--- a/core/res/res/values-watch/themes_device_defaults.xml
+++ b/core/res/res/values-watch/themes_device_defaults.xml
@@ -226,52 +226,6 @@
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorInverseOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorInversePrimary">@color/system_primary_light</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorInverseSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
     </style>
 
     <!-- DeviceDefault theme for a window that should look like the Settings app.  -->
@@ -376,8 +330,8 @@
         <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
     </style>
 
-   <!-- DeviceDefault theme for a window that will be displayed either full-screen on smaller
-    screens (small, normal) or as a dialog on larger screens (large, xlarge). -->
+    <!-- DeviceDefault theme for a window that will be displayed either full-screen on smaller
+     screens (small, normal) or as a dialog on larger screens (large, xlarge). -->
     <style name="Theme.DeviceDefault.DialogWhenLarge" parent="Theme.Material.DialogWhenLarge">
         <!-- Color palette Dark -->
         <item name="colorPrimary">@color/primary_device_default_dark</item>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 238aca5..792974d 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1217,178 +1217,6 @@
              a value of 'true' will not override any 'false' value in its parent chain nor will
              it prevent any 'false' in any of its children. -->
         <attr name="forceDarkAllowed" format="boolean" />
-
-        <!-- Dynamic Tokens -->
-
-        <!-- @hide -->
-        <attr name="materialColorBackground" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorControlActivated" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorControlHighlight" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorControlNormal" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorError" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorErrorContainer" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorInverseOnSurface" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorInversePrimary" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorInverseSurface" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnBackground" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnError" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnErrorContainer" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnPrimary" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnPrimaryContainer" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnSecondary" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnSecondaryContainer" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnSurface" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnSurfaceVariant" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnTertiary" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnTertiaryContainer" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOutline" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOutlineVariant" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorPaletteKeyColorNeutral" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorPaletteKeyColorNeutralVariant" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorPaletteKeyColorPrimary" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorPaletteKeyColorSecondary" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorPaletteKeyColorTertiary" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorPrimary" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorPrimaryContainer" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorScrim" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorSecondary" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorSecondaryContainer" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorShadow" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorSurface" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorSurfaceBright" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorSurfaceContainer" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorSurfaceContainerHigh" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorSurfaceContainerHighest" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorSurfaceContainerLow" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorSurfaceContainerLowest" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorSurfaceDim" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorSurfaceTint" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorSurfaceVariant" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorTertiary" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorTertiaryContainer" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorTextHintInverse" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorTextPrimaryInverse" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorTextPrimaryInverseDisableOnly" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorTextSecondaryAndTertiaryInverse" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorTextSecondaryAndTertiaryInverseDisabled" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnPrimaryFixed" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnPrimaryFixedVariant" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnSecondaryFixed" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnSecondaryFixedVariant" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnTertiaryFixed" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorOnTertiaryFixedVariant" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorPrimaryFixed" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorPrimaryFixedDim" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorSecondaryFixed" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorSecondaryFixedDim" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorTertiaryFixed" format="color"/>
-        <!-- @hide -->
-        <attr name="materialColorTertiaryFixedDim" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorBrandA" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorBrandB" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorBrandC" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorBrandD" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorClockHour" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorClockMinute" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorClockSecond" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorOnShadeActive" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorOnShadeActiveVariant" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorOnShadeInactive" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorOnShadeInactiveVariant" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorOnThemeApp" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorOverviewBackground" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorShadeActive" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorShadeDisabled" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorShadeInactive" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorThemeApp" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorThemeAppRing" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorThemeNotif" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorUnderSurface" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorWeatherTemp" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorWidgetBackground" format="color"/>
-
     </declare-styleable>
 
     <!-- **************************************************************** -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 00c59c6..a06d184 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2572,7 +2572,9 @@
              against a development branch, in which case it will only work against
              the development builds. -->
         <attr name="minSdkVersion" format="integer|string" />
-        <!-- @FlaggedApi(android.sdk.Flags.FLAG_MAJOR_MINOR_VERSIONING_SCHEME) -->
+        <!-- This is the minimum SDK major and minor version (e.g. "36.1") that
+             the application requires. Verified independently of minSdkVersion.
+             @FlaggedApi(android.sdk.Flags.FLAG_MAJOR_MINOR_VERSIONING_SCHEME) -->
         <attr name="minSdkVersionFull" format="string" />
         <!-- This is the SDK version number that the application is targeting.
              It is able to run on older versions (down to minSdkVersion), but
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 53b47622..89184bc 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -7212,10 +7212,6 @@
          screen. -->
     <bool name="config_dragToMaximizeInDesktopMode">false</bool>
 
-    <!-- Whether showing the app handle is supported on this device.
-         If config_isDesktopModeSupported, then this has no effect -->
-    <bool name="config_enableAppHandle">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>
diff --git a/core/res/res/values-watch-v36/config.xml b/core/res/res/values/config_watch.xml
similarity index 88%
rename from core/res/res/values-watch-v36/config.xml
rename to core/res/res/values/config_watch.xml
index 679dc70..629a343 100644
--- a/core/res/res/values-watch-v36/config.xml
+++ b/core/res/res/values/config_watch.xml
@@ -15,6 +15,8 @@
   -->
 
 <resources>
+    <!--  TODO(b/382103556): use predefined Material3 token  -->
+    <!-- For Wear Material3 -->
     <dimen name="config_wearMaterial3_buttonCornerRadius">26dp</dimen>
     <dimen name="config_wearMaterial3_bottomDialogCornerRadius">18dp</dimen>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index f53acbf..51bd4cc 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -912,6 +912,8 @@
     <dimen name="conversation_icon_size_badged">20dp</dimen>
     <!-- size of the conversation avatar in an expanded group -->
     <dimen name="conversation_avatar_size_group_expanded">@dimen/messaging_avatar_size</dimen>
+    <!-- size of the face pile icons (2025 redesign version) -->
+    <dimen name="notification_2025_face_pile_avatar_size">24dp</dimen>
     <!-- size of the face pile icons -->
     <dimen name="conversation_face_pile_avatar_size">32dp</dimen>
     <!-- size of the face pile icons when the group is expanded -->
@@ -939,6 +941,18 @@
     <!-- The size of the importance ring -->
     <dimen name="importance_ring_size">20dp</dimen>
 
+    <!-- The spacing around the app icon badge shown next to the conversation icon -->
+    <dimen name="notification_2025_conversation_icon_badge_padding">2dp</dimen>
+
+    <!-- Top and start margin for the app icon badge shown next to the conversation icon, to align
+        it to the bottom end corner.
+        40dp (conversation icon size) - 16dp (actual size of badge) - 2dp (badge padding) -->
+    <dimen name="notification_2025_conversation_icon_badge_position">22dp</dimen>
+
+    <!-- The size of the app icon badge shown next to the conversation icon, including its padding.
+        The actual size of the icon is 16dp, plus 2dp for each side for the padding. -->
+    <dimen name="notification_2025_conversation_icon_badge_size">20dp</dimen>
+
     <!-- The top padding of the conversation icon container in the regular state-->
     <dimen name="conversation_icon_container_top_padding">20dp</dimen>
 
diff --git a/core/res/res/values/dimens_watch.xml b/core/res/res/values/dimens_watch.xml
new file mode 100644
index 0000000..2aae987
--- /dev/null
+++ b/core/res/res/values/dimens_watch.xml
@@ -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.
+  -->
+
+<resources>
+    <!-- values for wear material3 button -->
+    <dimen name="btn_material_width">172dp</dimen>
+    <dimen name="btn_material_height">52dp</dimen>
+    <dimen name="btn_horizontal_edge_padding">14dp</dimen>
+    <dimen name="btn_drawable_padding">6dp</dimen>
+    <dimen name="btn_lineHeight">18sp</dimen>
+    <dimen name="btn_textSize">15sp</dimen>
+
+    <!-- values for wear material3 AlertDialog Title -->
+    <dimen name="alertDialog_material_line_height_title">18sp</dimen>
+    <dimen name="alertDialog_material_text_size_title">16sp</dimen>
+    <item name="alertDialog_material_letter_spacing_title" format="float" type="dimen">0.0125</item>
+    <dimen name="alertDialog_material_side_margin_title">@dimen/screen_percentage_12</dimen>
+
+    <!-- values for wear material3 AlertDialog Body -->
+    <dimen name="alertDialog_material_line_height_body_1">16sp</dimen>
+    <dimen name="alertDialog_material_text_size_body_1">14sp</dimen>
+    <item name="alertDialog_material_letter_spacing_body_1" format="float" type="dimen">0.0286</item>
+    <dimen name="alertDialog_material_side_margin_body">@dimen/screen_percentage_0416</dimen>
+
+    <!-- values for wear material3 AlertDialog -->
+    <dimen name="dialog_btn_negative_width">60dp</dimen>
+    <dimen name="dialog_btn_negative_height">60dp</dimen>
+    <dimen name="dialog_btn_confirm_width">62dp</dimen>
+    <dimen name="dialog_btn_confirm_height">60dp</dimen>
+    <dimen name="alertDialog_material_side_margin">@dimen/screen_percentage_052</dimen>
+    <dimen name="alertDialog_material_top_margin">@dimen/screen_percentage_10</dimen>
+    <dimen name="alertDialog_material_bottom_margin">@dimen/screen_percentage_3646</dimen>
+
+    <!-- Opacity factor for disabled wear material3 widget -->
+    <!-- Alpha transparency for widgets that set enablement/disablement programmatically
+       transparency is applied in the disabled state -->
+    <dimen name="disabled_alpha_device_default">0.12</dimen>
+    <!-- Alpha transparency applied to elements which are considered primary (e.g. primary text) -->
+    <dimen name="primary_content_alpha_device_default">0.38</dimen>
+
+    <!--  values for wear material3 progress bar(progress indicator)  -->
+    <item name="progressbar_inner_radius_ratio" format="float" type="dimen">2.12</item>
+    <dimen name="progressbar_thickness">8dp</dimen>
+    <dimen name="progressbar_elevation">0.1dp</dimen>
+
+    <!-- Alpha transparency for wigets that set enablement/disablement programmatically
+     transparency is applied in the disabled state -->
+    <dimen name="disabled_alpha_wear_material3">0.12</dimen>
+    <!-- Alpha transparency applied to elements which are considered primary (e.g. primary text) -->
+    <dimen name="primary_content_alpha_wear_material3">0.38</dimen>
+</resources>
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index 6c73b0c..a8cdc19 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -157,6 +157,19 @@
     <!-- @FlaggedApi(android.permission.flags.Flags.FLAG_SYSTEM_VENDOR_INTELLIGENCE_ROLE_ENABLED)
          @hide @SystemApi -->
     <public name="config_systemVendorIntelligence" />
+
+    <!-- @FlaggedApi(android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE)
+     @hide @SystemApi -->
+    <public name="config_defaultOnDeviceIntelligenceService"></public>
+
+    <!-- @FlaggedApi(android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE)
+     @hide @SystemApi -->
+    <public name="config_defaultOnDeviceSandboxedInferenceService"></public>
+
+    <!-- @FlaggedApi(android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE)
+     @hide @SystemApi -->
+    <public name="config_defaultOnDeviceIntelligenceDeviceConfigNamespace"></public>
+
   </staging-public-group>
 
   <staging-public-group type="dimen" first-id="0x01b30000">
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index acc1ff8..326afba 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -44,6 +44,10 @@
         <item name="textColor">@color/btn_colored_text_material</item>
     </style>
     <style name="Widget.DeviceDefault.Button.WearMaterial3"/>
+    <style name="Widget.DeviceDefault.Button.WearMaterial3.Filled"/>
+    <style name="Widget.DeviceDefault.Button.WearMaterial3.FilledTonal"/>
+    <style name="Widget.DeviceDefault.Button.WearMaterial3.Outlined"/>
+    <style name="Widget.DeviceDefault.Button.WearMaterial3.Text"/>
     <style name="Widget.DeviceDefault.TextView" parent="Widget.Material.TextView" />
     <style name="Widget.DeviceDefault.CheckedTextView" parent="Widget.Material.CheckedTextView"/>
     <style name="Widget.DeviceDefault.AutoCompleteTextView" parent="Widget.Material.AutoCompleteTextView"/>
@@ -60,6 +64,7 @@
     <style name="Widget.DeviceDefault.ProgressBar.Small" parent="Widget.Material.ProgressBar.Small"/>
     <style name="Widget.DeviceDefault.ProgressBar.Small.Title" parent="Widget.Material.ProgressBar.Small.Title"/>
     <style name="Widget.DeviceDefault.ProgressBar.Large" parent="Widget.Material.ProgressBar.Large"/>
+    <style name="Widget.DeviceDefault.ProgressBar.WearMaterial3"/>
     <style name="Widget.DeviceDefault.SeekBar" parent="Widget.Material.SeekBar"/>
     <style name="Widget.DeviceDefault.RatingBar" parent="Widget.Material.RatingBar"/>
     <style name="Widget.DeviceDefault.RatingBar.Indicator" parent="Widget.Material.RatingBar.Indicator"/>
@@ -430,6 +435,7 @@
     <!-- AlertDialog Styles -->
     <style name="AlertDialog.DeviceDefault" parent="AlertDialog.Material"/>
     <style name="AlertDialog.DeviceDefault.Light" parent="AlertDialog.Material.Light"/>
+    <style name="AlertDialog.DeviceDefault.WearMaterial3"/>
 
     <!-- Animation Styles -->
     <style name="Animation.DeviceDefault.Activity" parent="Animation.Material.Activity"/>
diff --git a/core/res/res/values/styles_watch.xml b/core/res/res/values/styles_watch.xml
new file mode 100644
index 0000000..3cf1f9b
--- /dev/null
+++ b/core/res/res/values/styles_watch.xml
@@ -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.
+  -->
+
+<resources>
+    <!-- TextAppearance for Wear Material3 Button - Filled  -->
+    <style name="TextAppearance.Widget.Button.Material.Filled">
+        <item name="textColor">@color/btn_material_filled_content_color_watch</item>
+    </style>
+
+    <!-- TextAppearance for Wear Material3 Button - Filled Tonal  -->
+    <style name="TextAppearance.Widget.Button.Material" parent="TextAppearance.DeviceDefault">
+        <item name="android:fontFamily">font-family-flex-device-default</item>
+        <item name="android:fontVariationSettings">"'wdth' 90, 'wght' 500, 'ROND' 100, 'opsz' 15, 'GRAD' 0"</item>
+        <item name="textSize">@dimen/btn_textSize</item>
+        <item name="textColor">@color/btn_material_filled_tonal_content_color_watch</item>
+        <item name="lineHeight">@dimen/btn_lineHeight</item>
+    </style>
+
+    <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3" parent="Widget.DeviceDefault.Button">
+        <item name="android:textSize">0sp</item>
+        <item name="android:gravity">center</item>
+        <item name="android:paddingStart">0dp</item>
+        <item name="android:paddingEnd">0dp</item>
+        <item name="android:drawablePadding">0dp</item>
+    </style>
+    <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3.Confirm">
+        <!-- Use a ImageView as background -->
+        <item name="background">@android:color/transparent</item>
+        <item name="minWidth">@dimen/dialog_btn_confirm_width</item>
+        <item name="minHeight">@dimen/dialog_btn_confirm_height</item>
+    </style>
+    <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3.Negative">
+        <item name="background">@drawable/dialog_alert_button_negative_watch</item>
+        <item name="minWidth">@dimen/dialog_btn_negative_width</item>
+        <item name="minHeight">@dimen/dialog_btn_negative_height</item>
+        <item name="maxWidth">@dimen/dialog_btn_negative_width</item>
+        <item name="maxHeight">@dimen/dialog_btn_negative_height</item>
+    </style>
+
+    <!-- TextAppearance for wear material3 AlertDialog Body  -->
+    <style name="TextAppearance.AlertDialog.Body1" parent="TextAppearance.Material.Body1">
+        <item name="android:fontFamily">font-family-flex-device-default</item>
+        <item name="android:fontVariationSettings">"'wdth' 90, 'wght' 450, 'ROND' 100, 'GRAD' 0"</item>
+        <item name="android:textSize">@dimen/alertDialog_material_text_size_body_1</item>
+        <item name="android:lineHeight">@dimen/alertDialog_material_line_height_body_1</item>
+        <item name="android:letterSpacing">@dimen/alertDialog_material_letter_spacing_body_1</item>
+    </style>
+
+    <!-- TextAppearance for wear material3 AlertDialog Title  -->
+    <style name="TextAppearance.AlertDialog.Title" parent="TextAppearance.Material.Title">
+        <item name="android:fontFamily">font-family-flex-device-default</item>
+        <item name="android:fontVariationSettings">"'wdth' 100, 'wght' 550, 'ROND' 100, 'GRAD' 0"</item>
+        <item name="android:textSize">@dimen/alertDialog_material_text_size_title</item>
+        <item name="android:lineHeight">@dimen/alertDialog_material_line_height_title</item>
+        <item name="android:letterSpacing">@dimen/alertDialog_material_letter_spacing_title</item>
+        <item name="android:maxLines">2</item>
+        <item name="android:shadowRadius">0</item>
+        <item name="android:ellipsize">end</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 28de553..6c01994 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -5445,133 +5445,51 @@
   <java-symbol name="customColorWeatherTemp" type="color"/>
   <java-symbol name="customColorWidgetBackground" type="color"/>
 
-  <java-symbol type="attr" name="materialColorBackground"/>
-  <java-symbol type="attr" name="materialColorControlActivated"/>
-  <java-symbol type="attr" name="materialColorControlHighlight"/>
-  <java-symbol type="attr" name="materialColorControlNormal"/>
-  <java-symbol type="attr" name="materialColorError"/>
-  <java-symbol type="attr" name="materialColorErrorContainer"/>
-  <java-symbol type="attr" name="materialColorInverseOnSurface"/>
-  <java-symbol type="attr" name="materialColorInversePrimary"/>
-  <java-symbol type="attr" name="materialColorInverseSurface"/>
-  <java-symbol type="attr" name="materialColorOnBackground"/>
-  <java-symbol type="attr" name="materialColorOnError"/>
-  <java-symbol type="attr" name="materialColorOnErrorContainer"/>
-  <java-symbol type="attr" name="materialColorOnPrimary"/>
-  <java-symbol type="attr" name="materialColorOnPrimaryContainer"/>
-  <java-symbol type="attr" name="materialColorOnSecondary"/>
-  <java-symbol type="attr" name="materialColorOnSecondaryContainer"/>
-  <java-symbol type="attr" name="materialColorOnSurface"/>
-  <java-symbol type="attr" name="materialColorOnSurfaceVariant"/>
-  <java-symbol type="attr" name="materialColorOnTertiary"/>
-  <java-symbol type="attr" name="materialColorOnTertiaryContainer"/>
-  <java-symbol type="attr" name="materialColorOutline"/>
-  <java-symbol type="attr" name="materialColorOutlineVariant"/>
-  <java-symbol type="attr" name="materialColorPaletteKeyColorNeutral"/>
-  <java-symbol type="attr" name="materialColorPaletteKeyColorNeutralVariant"/>
-  <java-symbol type="attr" name="materialColorPaletteKeyColorPrimary"/>
-  <java-symbol type="attr" name="materialColorPaletteKeyColorSecondary"/>
-  <java-symbol type="attr" name="materialColorPaletteKeyColorTertiary"/>
-  <java-symbol type="attr" name="materialColorPrimary"/>
-  <java-symbol type="attr" name="materialColorPrimaryContainer"/>
-  <java-symbol type="attr" name="materialColorScrim"/>
-  <java-symbol type="attr" name="materialColorSecondary"/>
-  <java-symbol type="attr" name="materialColorSecondaryContainer"/>
-  <java-symbol type="attr" name="materialColorShadow"/>
-  <java-symbol type="attr" name="materialColorSurface"/>
-  <java-symbol type="attr" name="materialColorSurfaceBright"/>
-  <java-symbol type="attr" name="materialColorSurfaceContainer"/>
-  <java-symbol type="attr" name="materialColorSurfaceContainerHigh"/>
-  <java-symbol type="attr" name="materialColorSurfaceContainerHighest"/>
-  <java-symbol type="attr" name="materialColorSurfaceContainerLow"/>
-  <java-symbol type="attr" name="materialColorSurfaceContainerLowest"/>
-  <java-symbol type="attr" name="materialColorSurfaceDim"/>
-  <java-symbol type="attr" name="materialColorSurfaceTint"/>
-  <java-symbol type="attr" name="materialColorSurfaceVariant"/>
-  <java-symbol type="attr" name="materialColorTertiary"/>
-  <java-symbol type="attr" name="materialColorTertiaryContainer"/>
-  <java-symbol type="attr" name="materialColorTextHintInverse"/>
-  <java-symbol type="attr" name="materialColorTextPrimaryInverse"/>
-  <java-symbol type="attr" name="materialColorTextPrimaryInverseDisableOnly"/>
-  <java-symbol type="attr" name="materialColorTextSecondaryAndTertiaryInverse"/>
-  <java-symbol type="attr" name="materialColorTextSecondaryAndTertiaryInverseDisabled"/>
-  <java-symbol type="attr" name="materialColorOnPrimaryFixed"/>
-  <java-symbol type="attr" name="materialColorOnPrimaryFixedVariant"/>
-  <java-symbol type="attr" name="materialColorOnSecondaryFixed"/>
-  <java-symbol type="attr" name="materialColorOnSecondaryFixedVariant"/>
-  <java-symbol type="attr" name="materialColorOnTertiaryFixed"/>
-  <java-symbol type="attr" name="materialColorOnTertiaryFixedVariant"/>
-  <java-symbol type="attr" name="materialColorPrimaryFixed"/>
-  <java-symbol type="attr" name="materialColorPrimaryFixedDim"/>
-  <java-symbol type="attr" name="materialColorSecondaryFixed"/>
-  <java-symbol type="attr" name="materialColorSecondaryFixedDim"/>
-  <java-symbol type="attr" name="materialColorTertiaryFixed"/>
-  <java-symbol type="attr" name="materialColorTertiaryFixedDim"/>
-  <java-symbol type="attr" name="customColorBrandA"/>
-  <java-symbol type="attr" name="customColorBrandB"/>
-  <java-symbol type="attr" name="customColorBrandC"/>
-  <java-symbol type="attr" name="customColorBrandD"/>
-  <java-symbol type="attr" name="customColorClockHour"/>
-  <java-symbol type="attr" name="customColorClockMinute"/>
-  <java-symbol type="attr" name="customColorClockSecond"/>
-  <java-symbol type="attr" name="customColorOnShadeActive"/>
-  <java-symbol type="attr" name="customColorOnShadeActiveVariant"/>
-  <java-symbol type="attr" name="customColorOnShadeInactive"/>
-  <java-symbol type="attr" name="customColorOnShadeInactiveVariant"/>
-  <java-symbol type="attr" name="customColorOnThemeApp"/>
-  <java-symbol type="attr" name="customColorOverviewBackground"/>
-  <java-symbol type="attr" name="customColorShadeActive"/>
-  <java-symbol type="attr" name="customColorShadeDisabled"/>
-  <java-symbol type="attr" name="customColorShadeInactive"/>
-  <java-symbol type="attr" name="customColorThemeApp"/>
-  <java-symbol type="attr" name="customColorThemeAppRing"/>
-  <java-symbol type="attr" name="customColorThemeNotif"/>
-  <java-symbol type="attr" name="customColorUnderSurface"/>
-  <java-symbol type="attr" name="customColorWeatherTemp"/>
-  <java-symbol type="attr" name="customColorWidgetBackground"/>
-
-  <java-symbol name="system_widget_background_light" type="color"/>
-  <java-symbol name="system_clock_hour_light" type="color"/>
-  <java-symbol name="system_clock_minute_light" type="color"/>
-  <java-symbol name="system_clock_second_light" type="color"/>
-  <java-symbol name="system_theme_app_light" type="color"/>
-  <java-symbol name="system_on_theme_app_light" type="color"/>
-  <java-symbol name="system_theme_app_ring_light" type="color"/>
-  <java-symbol name="system_theme_notif_light" type="color"/>
   <java-symbol name="system_brand_a_light" type="color"/>
   <java-symbol name="system_brand_b_light" type="color"/>
   <java-symbol name="system_brand_c_light" type="color"/>
   <java-symbol name="system_brand_d_light" type="color"/>
-  <java-symbol name="system_under_surface_light" type="color"/>
-  <java-symbol name="system_shade_active_light" type="color"/>
+  <java-symbol name="system_clock_hour_light" type="color"/>
+  <java-symbol name="system_clock_minute_light" type="color"/>
+  <java-symbol name="system_clock_second_light" type="color"/>
   <java-symbol name="system_on_shade_active_light" type="color"/>
   <java-symbol name="system_on_shade_active_variant_light" type="color"/>
-  <java-symbol name="system_shade_inactive_light" type="color"/>
   <java-symbol name="system_on_shade_inactive_light" type="color"/>
   <java-symbol name="system_on_shade_inactive_variant_light" type="color"/>
-  <java-symbol name="system_shade_disabled_light" type="color"/>
+  <java-symbol name="system_on_theme_app_light" type="color"/>
   <java-symbol name="system_overview_background_light" type="color"/>
-  <java-symbol name="system_widget_background_dark" type="color"/>
-  <java-symbol name="system_clock_hour_dark" type="color"/>
-  <java-symbol name="system_clock_minute_dark" type="color"/>
-  <java-symbol name="system_clock_second_dark" type="color"/>
-  <java-symbol name="system_theme_app_dark" type="color"/>
-  <java-symbol name="system_on_theme_app_dark" type="color"/>
-  <java-symbol name="system_theme_app_ring_dark" type="color"/>
-  <java-symbol name="system_theme_notif_dark" type="color"/>
+  <java-symbol name="system_shade_active_light" type="color"/>
+  <java-symbol name="system_shade_disabled_light" type="color"/>
+  <java-symbol name="system_shade_inactive_light" type="color"/>
+  <java-symbol name="system_theme_app_light" type="color"/>
+  <java-symbol name="system_theme_app_ring_light" type="color"/>
+  <java-symbol name="system_theme_notif_light" type="color"/>
+  <java-symbol name="system_under_surface_light" type="color"/>
+  <java-symbol name="system_weather_temp_light" type="color"/>
+  <java-symbol name="system_widget_background_light" type="color"/>
+
   <java-symbol name="system_brand_a_dark" type="color"/>
   <java-symbol name="system_brand_b_dark" type="color"/>
   <java-symbol name="system_brand_c_dark" type="color"/>
   <java-symbol name="system_brand_d_dark" type="color"/>
-  <java-symbol name="system_under_surface_dark" type="color"/>
-  <java-symbol name="system_shade_active_dark" type="color"/>
+  <java-symbol name="system_clock_hour_dark" type="color"/>
+  <java-symbol name="system_clock_minute_dark" type="color"/>
+  <java-symbol name="system_clock_second_dark" type="color"/>
   <java-symbol name="system_on_shade_active_dark" type="color"/>
   <java-symbol name="system_on_shade_active_variant_dark" type="color"/>
-  <java-symbol name="system_shade_inactive_dark" type="color"/>
   <java-symbol name="system_on_shade_inactive_dark" type="color"/>
   <java-symbol name="system_on_shade_inactive_variant_dark" type="color"/>
-  <java-symbol name="system_shade_disabled_dark" type="color"/>
+  <java-symbol name="system_on_theme_app_dark" type="color"/>
   <java-symbol name="system_overview_background_dark" type="color"/>
+  <java-symbol name="system_shade_active_dark" type="color"/>
+  <java-symbol name="system_shade_disabled_dark" type="color"/>
+  <java-symbol name="system_shade_inactive_dark" type="color"/>
+  <java-symbol name="system_theme_app_dark" type="color"/>
+  <java-symbol name="system_theme_app_ring_dark" type="color"/>
+  <java-symbol name="system_theme_notif_dark" type="color"/>
+  <java-symbol name="system_under_surface_dark" type="color"/>
+  <java-symbol name="system_weather_temp_dark" type="color"/>
+  <java-symbol name="system_widget_background_dark" type="color"/>
 
   <java-symbol type="attr" name="actionModeUndoDrawable" />
   <java-symbol type="attr" name="actionModeRedoDrawable" />
@@ -5763,9 +5681,6 @@
        screen. -->
   <java-symbol type="bool" name="config_dragToMaximizeInDesktopMode" />
 
-  <!-- Whether showing the app handle is supported on this device -->
-  <java-symbol type="bool" name="config_enableAppHandle" />
-
   <!-- Frame rate compatibility value for Wallpaper -->
   <java-symbol type="integer" name="config_wallpaperFrameRateCompatibility" />
 
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index d8346d8..6b3d427 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -131,7 +131,7 @@
         <item name="progressBarStyleSmallInverse">@style/Widget.DeviceDefault.ProgressBar.Small.Inverse</item>
         <item name="progressBarStyleLargeInverse">@style/Widget.DeviceDefault.ProgressBar.Large.Inverse</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="seekBarStyle">@style/Widget.DeviceDefault.SeekBar</item>
         <item name="ratingBarStyle">@style/Widget.DeviceDefault.RatingBar</item>
         <item name="ratingBarStyleIndicator">@style/Widget.DeviceDefault.RatingBar.Indicator</item>
@@ -238,91 +238,6 @@
         <item name="textColorOnAccent">@color/system_on_primary_dark</item>
         <item name="colorForeground">@color/foreground_device_default_dark</item>
         <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <style name="Theme.DeviceDefault" parent="Theme.DeviceDefaultBase" />
@@ -368,96 +283,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar.  This theme
@@ -502,96 +332,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar and
@@ -638,96 +383,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} that has no title bar and translucent
@@ -773,96 +433,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <!-- DeviceDefault theme for dialog windows and activities. This changes the window to be
@@ -916,96 +491,11 @@
         <item name="alertDialogTheme">@style/Theme.DeviceDefault.Dialog.Alert</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog} that has a nice minimum width for a
@@ -1050,96 +540,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog} without an action bar -->
@@ -1183,96 +588,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog_NoActionBar} that has a nice minimum width
@@ -1317,96 +637,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
@@ -1467,96 +702,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <!-- DeviceDefault theme for a window without an action bar that will be displayed either
@@ -1602,96 +752,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <!-- DeviceDefault theme for a presentation window on a secondary display. -->
@@ -1735,96 +800,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <!-- DeviceDefault theme for panel windows. This removes all extraneous window
@@ -1870,96 +850,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
@@ -2004,96 +899,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
@@ -2138,96 +948,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <!-- DeviceDefault style for input methods, which is used by the
@@ -2272,96 +997,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- DeviceDefault style for input methods, which is used by the
@@ -2406,96 +1046,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Material.Dialog.Alert">
@@ -2540,96 +1095,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <!-- Theme for the dialog shown when an app crashes or ANRs. -->
@@ -2679,96 +1149,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <style name="Theme.DeviceDefault.Dialog.NoFrame" parent="Theme.Material.Dialog.NoFrame">
@@ -2811,96 +1196,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with a light-colored style -->
@@ -2982,7 +1282,7 @@
         <item name="progressBarStyleSmallInverse">@style/Widget.DeviceDefault.Light.ProgressBar.Small.Inverse</item>
         <item name="progressBarStyleLargeInverse">@style/Widget.DeviceDefault.Light.ProgressBar.Large.Inverse</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="seekBarStyle">@style/Widget.DeviceDefault.Light.SeekBar</item>
         <item name="ratingBarStyle">@style/Widget.DeviceDefault.Light.RatingBar</item>
         <item name="ratingBarStyleIndicator">@style/Widget.DeviceDefault.Light.RatingBar.Indicator</item>
@@ -3086,91 +1386,6 @@
         <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
         <item name="colorPopupBackground">?attr/colorBackgroundFloating</item>
         <item name="panelColorBackground">?attr/colorBackgroundFloating</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- Variant of the DeviceDefault (light) theme that has a solid (opaque) action bar with an
@@ -3215,96 +1430,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar -->
@@ -3348,96 +1478,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar.
@@ -3482,96 +1527,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar
@@ -3618,96 +1578,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} that has no title bar and translucent
@@ -3753,96 +1628,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- DeviceDefault light theme for dialog windows and activities. This changes the window to be
@@ -3894,96 +1684,11 @@
         <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} that has a nice minimum width for a
@@ -4031,96 +1736,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} without an action bar -->
@@ -4167,96 +1787,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog_NoActionBar} that has a nice minimum
@@ -4304,96 +1839,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
@@ -4427,91 +1877,6 @@
         <item name="textColorOnAccent">@color/system_on_primary_dark</item>
         <item name="colorForeground">@color/foreground_device_default_light</item>
         <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- Variant of Theme.DeviceDefault.Dialog.NoActionBar that has a fixed size. -->
@@ -4545,91 +1910,6 @@
         <item name="textColorOnAccent">@color/system_on_primary_dark</item>
         <item name="colorForeground">@color/foreground_device_default_light</item>
         <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- DeviceDefault light theme for a window that will be displayed either full-screen on smaller
@@ -4677,96 +1957,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- DeviceDefault light theme for a window without an action bar that will be displayed either
@@ -4815,96 +2010,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- DeviceDefault light theme for a presentation window on a secondary display. -->
@@ -4951,96 +2061,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- DeviceDefault light theme for panel windows. This removes all extraneous window
@@ -5086,96 +2111,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Material.Light.Dialog.Alert">
@@ -5220,96 +2160,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Dialog.Alert.DayNight" parent="Theme.DeviceDefault.Light.Dialog.Alert" />
@@ -5354,96 +2209,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Light.Voice" parent="Theme.Material.Light.Voice">
@@ -5486,96 +2256,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- DeviceDefault theme for a window that should look like the Settings app.  -->
@@ -5631,90 +2316,6 @@
         <item name="colorListDivider">@color/list_divider_color_light</item>
         <item name="opacityListDivider">@color/list_divider_opacity_device_default_light</item>
 
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.SystemUI" parent="Theme.DeviceDefault.Light">
@@ -5745,96 +2346,12 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
 
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.SystemUI.Dialog" parent="Theme.DeviceDefault.Light.Dialog">
@@ -5857,96 +2374,12 @@
         <item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
 
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Settings_Dark} with no action bar -->
@@ -5991,96 +2424,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.DialogBase" parent="Theme.Material.Light.BaseDialog">
@@ -6114,91 +2462,6 @@
 
         <!-- Dialog attributes -->
         <item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.Dialog" parent="Theme.DeviceDefault.Settings.DialogBase">
@@ -6216,7 +2479,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -6267,96 +2530,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.Dialog.Alert" parent="Theme.Material.Settings.Dialog.Alert">
@@ -6403,96 +2581,11 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+        <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.Dialog.NoActionBar" parent="Theme.DeviceDefault.Light.Dialog.NoActionBar" />
@@ -6570,91 +2663,6 @@
         <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
         <item name="colorAccentSecondary">@color/system_secondary_dark</item>
         <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <style name="ThemeOverlay.DeviceDefault.Accent.Light">
@@ -6662,91 +2670,6 @@
         <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
         <item name="colorAccentSecondary">@color/system_secondary_dark</item>
         <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <!-- Theme overlay that replaces colorAccent with the colorAccent from {@link #Theme_DeviceDefault_DayNight}. -->
@@ -6758,91 +2681,6 @@
         <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
         <item name="colorAccentSecondary">@color/system_secondary_dark</item>
         <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
 
     <style name="Theme.DeviceDefault.Light.Dialog.Alert.UserSwitchingDialog" parent="Theme.DeviceDefault.NoActionBar.Fullscreen">
@@ -6850,91 +2688,6 @@
         <item name="colorBackgroundFloating">@color/background_device_default_light</item>
         <item name="layout_gravity">center</item>
         <item name="windowAnimationStyle">@style/Animation.DeviceDefault.Dialog</item>
-
-        <item name="materialColorBackground">@color/system_background_light</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_light</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_light</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_light</item>
-        <item name="materialColorError">@color/system_error_light</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_light</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item>
-        <item name="materialColorOnBackground">@color/system_on_background_light</item>
-        <item name="materialColorOnError">@color/system_on_error_light</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_light</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
-        <item name="materialColorOutline">@color/system_outline_light</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item>
-        <item name="materialColorPrimary">@color/system_primary_light</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
-        <item name="materialColorScrim">@color/system_scrim_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
-        <item name="materialColorShadow">@color/system_shadow_light</item>
-        <item name="materialColorSurface">@color/system_surface_light</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_light</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Notification" parent="@style/Theme.Material.Notification">
@@ -6953,91 +2706,6 @@
         <item name="colorAccentPrimary">@color/system_accent1_100</item>
         <item name="textColorPrimary">@color/system_neutral1_900</item>
         <item name="textColorSecondary">@color/system_neutral2_700</item>
-
-        <item name="materialColorBackground">@color/system_background_dark</item>
-        <item name="materialColorControlActivated">@color/system_control_activated_dark</item>
-        <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item>
-        <item name="materialColorControlNormal">@color/system_control_normal_dark</item>
-        <item name="materialColorError">@color/system_error_dark</item>
-        <item name="materialColorErrorContainer">@color/system_error_container_dark</item>
-        <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item>
-        <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item>
-        <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item>
-        <item name="materialColorOnBackground">@color/system_on_background_dark</item>
-        <item name="materialColorOnError">@color/system_on_error_dark</item>
-        <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
-        <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
-        <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
-        <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
-        <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
-        <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
-        <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
-        <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
-        <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
-        <item name="materialColorOutline">@color/system_outline_dark</item>
-        <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
-        <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item>
-        <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item>
-        <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item>
-        <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item>
-        <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item>
-        <item name="materialColorPrimary">@color/system_primary_dark</item>
-        <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
-        <item name="materialColorScrim">@color/system_scrim_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
-        <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
-        <item name="materialColorShadow">@color/system_shadow_dark</item>
-        <item name="materialColorSurface">@color/system_surface_dark</item>
-        <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-        <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
-        <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
-        <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
-        <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
-        <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item>
-        <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
-        <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
-        <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item>
-        <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item>
-        <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item>
-        <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
-        <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
-        <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
-        <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
-        <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
-        <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
-        <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
-        <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
-        <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
-        <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
-        <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
-        <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item>
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
     </style>
     <style name="Theme.DeviceDefault.AutofillHalfScreenDialogList" parent="Theme.DeviceDefault.DayNight">
         <item name="colorListDivider">@color/list_divider_opacity_device_default_light</item>
diff --git a/core/res/res/xml/bookmarks.xml b/core/res/res/xml/bookmarks.xml
index e735784..17860ef 100644
--- a/core/res/res/xml/bookmarks.xml
+++ b/core/res/res/xml/bookmarks.xml
@@ -20,14 +20,10 @@
 
      Typical shortcuts (not necessarily defined here):
        'b': Browser
-       'c': Contacts
+       'p': Contacts
        'e': Email
-       'g': GMail
-       'k': Calendar
+       'c': Calendar
        'm': Maps
-       'p': Music
-       's': SMS
-       't': Talk
        'u': Calculator
        'y': YouTube
 -->
@@ -38,7 +34,7 @@
         androidprv:modifierState="META" />
     <bookmark
         category="android.intent.category.APP_CONTACTS"
-        androidprv:keycode="KEYCODE_C"
+        androidprv:keycode="KEYCODE_P"
         androidprv:modifierState="META" />
     <bookmark
         category="android.intent.category.APP_EMAIL"
@@ -46,21 +42,13 @@
         androidprv:modifierState="META" />
     <bookmark
         category="android.intent.category.APP_CALENDAR"
-        androidprv:keycode="KEYCODE_K"
+        androidprv:keycode="KEYCODE_C"
         androidprv:modifierState="META" />
     <bookmark
         category="android.intent.category.APP_MAPS"
         androidprv:keycode="KEYCODE_M"
         androidprv:modifierState="META" />
     <bookmark
-        category="android.intent.category.APP_MUSIC"
-        androidprv:keycode="KEYCODE_P"
-        androidprv:modifierState="META" />
-    <bookmark
-        role="android.app.role.SMS"
-        androidprv:keycode="KEYCODE_S"
-        androidprv:modifierState="META" />
-    <bookmark
         category="android.intent.category.APP_CALCULATOR"
         androidprv:keycode="KEYCODE_U"
         androidprv:modifierState="META" />
diff --git a/core/tests/coretests/src/android/app/NotificationManagerTest.java b/core/tests/coretests/src/android/app/NotificationManagerTest.java
new file mode 100644
index 0000000..3213abe
--- /dev/null
+++ b/core/tests/coretests/src/android/app/NotificationManagerTest.java
@@ -0,0 +1,151 @@
+/*
+ * 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;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.time.Instant;
+import java.time.InstantSource;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class NotificationManagerTest {
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+    private Context mContext;
+    private NotificationManagerWithMockService mNotificationManager;
+    private final FakeClock mClock = new FakeClock();
+
+    @Before
+    public void setUp() {
+        mContext = ApplicationProvider.getApplicationContext();
+        mNotificationManager = new NotificationManagerWithMockService(mContext, mClock);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
+    public void notify_rapidUpdate_isThrottled() throws Exception {
+        Notification n = exampleNotification();
+
+        for (int i = 0; i < 100; i++) {
+            mNotificationManager.notify(1, n);
+            mClock.advanceByMillis(5);
+        }
+
+        verify(mNotificationManager.mBackendService, atMost(30)).enqueueNotificationWithTag(any(),
+                any(), any(), anyInt(), any(), anyInt());
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
+    public void notify_reasonableUpdate_isNotThrottled() throws Exception {
+        Notification n = exampleNotification();
+
+        for (int i = 0; i < 100; i++) {
+            mNotificationManager.notify(1, n);
+            mClock.advanceByMillis(300);
+        }
+
+        verify(mNotificationManager.mBackendService, times(100)).enqueueNotificationWithTag(any(),
+                any(), any(), anyInt(), any(), anyInt());
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
+    public void notify_rapidAdd_isNotThrottled() throws Exception {
+        Notification n = exampleNotification();
+
+        for (int i = 0; i < 100; i++) {
+            mNotificationManager.notify(i, n);
+            mClock.advanceByMillis(5);
+        }
+
+        verify(mNotificationManager.mBackendService, times(100)).enqueueNotificationWithTag(any(),
+                any(), any(), anyInt(), any(), anyInt());
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
+    public void notify_rapidAddAndCancel_isNotThrottled() throws Exception {
+        Notification n = exampleNotification();
+
+        for (int i = 0; i < 100; i++) {
+            mNotificationManager.notify(1, n);
+            mNotificationManager.cancel(1);
+            mClock.advanceByMillis(5);
+        }
+
+        verify(mNotificationManager.mBackendService, times(100)).enqueueNotificationWithTag(any(),
+                any(), any(), anyInt(), any(), anyInt());
+    }
+
+    private Notification exampleNotification() {
+        return new Notification.Builder(mContext, "channel")
+                .setSmallIcon(android.R.drawable.star_big_on)
+                .build();
+    }
+
+    private static class NotificationManagerWithMockService extends NotificationManager {
+
+        private final INotificationManager mBackendService;
+
+        NotificationManagerWithMockService(Context context, InstantSource clock) {
+            super(context, clock);
+            mBackendService = mock(INotificationManager.class);
+        }
+
+        @Override
+        public INotificationManager service() {
+            return mBackendService;
+        }
+    }
+
+    private static class FakeClock implements InstantSource {
+
+        private long mNowMillis = 441644400000L;
+
+        @Override
+        public Instant instant() {
+            return Instant.ofEpochMilli(mNowMillis);
+        }
+
+        private void advanceByMillis(long millis) {
+            mNowMillis += millis;
+        }
+    }
+}
diff --git a/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java b/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java
index 6d2dd53..ff3abae 100644
--- a/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java
+++ b/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java
@@ -33,7 +33,6 @@
 import android.os.FileUtils;
 import android.os.ParcelFileDescriptor;
 import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.util.ArraySet;
 import android.util.PackageUtils;
 
@@ -62,7 +61,6 @@
 import java.util.Set;
 
 @Presubmit
-@RequiresFlagsEnabled(android.content.pm.Flags.FLAG_SDK_DEPENDENCY_INSTALLER)
 public class ApkLiteParseUtilsTest {
 
     @Rule
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteRawStatementTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteRawStatementTest.java
index 6dad3b7..51a43ac0 100644
--- a/core/tests/coretests/src/android/database/sqlite/SQLiteRawStatementTest.java
+++ b/core/tests/coretests/src/android/database/sqlite/SQLiteRawStatementTest.java
@@ -1010,6 +1010,7 @@
         mDatabase.beginTransaction();
         try {
             mDatabase.execSQL("CREATE TABLE t1 (i int, j int);");
+            mDatabase.execSQL("INSERT INTO t1 (i, j) VALUES (2, 20)");
             mDatabase.setTransactionSuccessful();
         } finally {
             mDatabase.endTransaction();
@@ -1017,13 +1018,58 @@
 
         mDatabase.beginTransactionReadOnly();
         try (SQLiteRawStatement s = mDatabase.createRawStatement("SELECT * from t1")) {
-            s.step();
-            s.getColumnText(5); // out-of-range column
+            assertTrue(s.step());
+            s.getColumnText(5); // out-of-range column: the range is [0,2).
             fail("JNI exception not thrown");
         } catch (SQLiteBindOrColumnIndexOutOfRangeException e) {
             // Passing case.
         } finally {
             mDatabase.endTransaction();
         }
+
+        mDatabase.beginTransactionReadOnly();
+        try (SQLiteRawStatement s = mDatabase.createRawStatement("SELECT * from t1")) {
+            // Do not step the statement.  The column count will be zero.
+            s.getColumnText(5); // out-of-range column: never stepped.
+            fail("JNI exception not thrown");
+        } catch (SQLiteMisuseException e) {
+            // Passing case.
+        } finally {
+            mDatabase.endTransaction();
+        }
+
+        mDatabase.beginTransactionReadOnly();
+        try (SQLiteRawStatement s = mDatabase.createRawStatement("SELECT * from t1")) {
+            // Do not step the statement.  The column count will be zero.
+            s.getColumnText(0); // out-of-range column: never stepped.
+            fail("JNI exception not thrown");
+        } catch (SQLiteMisuseException e) {
+            // Passing case.
+        } finally {
+            mDatabase.endTransaction();
+        }
+
+        // Ensure that column names and column types can be fetched even if the statement is not
+        // stepped.  A new SQL statement is created to avoid interaction from the statement cache.
+        mDatabase.beginTransactionReadOnly();
+        try (SQLiteRawStatement s = mDatabase.createRawStatement("SELECT * from t1 WHERE j = 3")) {
+            // Do not step the statement.
+            assertEquals("i", s.getColumnName(0));
+            assertEquals("j", s.getColumnName(1));
+        } finally {
+            mDatabase.endTransaction();
+        }
+
+        mDatabase.beginTransactionReadOnly();
+        try (SQLiteRawStatement s = mDatabase.createRawStatement("SELECT * from t1")) {
+            // Do not step the statement.
+            s.getColumnName(3); // out-of-range column
+            fail("JNI exception not thrown");
+        } catch (SQLiteBindOrColumnIndexOutOfRangeException e) {
+            // Passing case.
+        } finally {
+            mDatabase.endTransaction();
+        }
+
     }
 }
diff --git a/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt b/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt
index 18e4fde..4a227d8 100644
--- a/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt
+++ b/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt
@@ -318,11 +318,11 @@
         verifyDisplay(actualDisplay2, id = 2, width = 200f, height = 600f, POSITION_RIGHT,
             offset = 0f, noOfChildren = 2)
 
-        val actualDisplay3 = actualDisplay2.children[1]
+        val actualDisplay3 = actualDisplay2.children[0]
         verifyDisplay(actualDisplay3, id = 3, width = 600f, height = 200f, POSITION_RIGHT,
             offset = 10f, noOfChildren = 0)
 
-        val actualDisplay4 = actualDisplay2.children[0]
+        val actualDisplay4 = actualDisplay2.children[1]
         verifyDisplay(actualDisplay4, id = 4, width = 200f, height = 600f, POSITION_RIGHT,
             offset = 210f, noOfChildren = 0)
     }
@@ -402,42 +402,46 @@
 
     @Test
     fun rearrange_twoDisplays() {
-        val nodes = rearrangeRects(
+        val root = rearrangeRects(
             // Arrange in staggered manner, connected vertically.
             RectF(100f, 100f, 250f, 200f),
             RectF(150f, 200f, 300f, 300f),
         )
 
-        assertThat(nodes[0].children).containsExactly(nodes[1])
-        assertThat(nodes[1].children).isEmpty()
-        assertPositioning(nodes, Pair(POSITION_BOTTOM, 50f))
+        verifyDisplay(root, id = 0, width = 150f, height = 100f, noOfChildren = 1)
+        val node = root.children[0]
+        verifyDisplay(
+                node, id = 1, width = 150f, height = 100f, POSITION_BOTTOM, offset = 50f,
+                noOfChildren = 0)
     }
 
     @Test
     fun rearrange_reverseOrderOfSeveralDisplays() {
-        val nodes = rearrangeRects(
+        val root = rearrangeRects(
             RectF(0f, 0f, 150f, 100f),
             RectF(-150f, 0f, 0f, 100f),
             RectF(-300f, 0f, -150f, 100f),
             RectF(-450f, 0f, -300f, 100f),
         )
 
-        assertPositioning(
-            nodes,
-            Pair(POSITION_LEFT, 0f),
-            Pair(POSITION_LEFT, 0f),
-            Pair(POSITION_LEFT, 0f),
-        )
-
-        assertThat(nodes[0].children).containsExactly(nodes[1])
-        assertThat(nodes[1].children).containsExactly(nodes[2])
-        assertThat(nodes[2].children).containsExactly(nodes[3])
-        assertThat(nodes[3].children).isEmpty()
+        verifyDisplay(root, id = 0, width = 150f, height = 100f, noOfChildren = 1)
+        var node = root.children[0]
+        verifyDisplay(
+                node, id = 1, width = 150f, height = 100f, POSITION_LEFT, offset = 0f,
+                noOfChildren = 1)
+        node = node.children[0]
+        verifyDisplay(
+                node, id = 2, width = 150f, height = 100f, POSITION_LEFT, offset = 0f,
+                noOfChildren = 1)
+        node = node.children[0]
+        verifyDisplay(
+                node, id = 3, width = 150f, height = 100f, POSITION_LEFT, offset = 0f,
+                noOfChildren = 0)
     }
 
     @Test
     fun rearrange_crossWithRootInCenter() {
-        val nodes = rearrangeRects(
+        val root = rearrangeRects(
             RectF(0f, 0f, 150f, 100f),
             RectF(-150f, 0f, 0f, 100f),
             RectF(0f, -100f, 150f, 0f),
@@ -445,21 +449,24 @@
             RectF(0f, 100f, 150f, 200f),
         )
 
-        assertPositioning(
-            nodes,
-            Pair(POSITION_LEFT, 0f),
-            Pair(POSITION_TOP, 0f),
-            Pair(POSITION_RIGHT, 0f),
-            Pair(POSITION_BOTTOM, 0f),
-        )
-
-        assertThat(nodes[0].children)
-            .containsExactly(nodes[1], nodes[2], nodes[3], nodes[4])
+        verifyDisplay(root, id = 0, width = 150f, height = 100f, noOfChildren = 4)
+        verifyDisplay(
+                root.children[0], id = 1, width = 150f, height = 100f, POSITION_LEFT, offset = 0f,
+                noOfChildren = 0)
+        verifyDisplay(
+                root.children[1], id = 2, width = 150f, height = 100f, POSITION_TOP, offset = 0f,
+                noOfChildren = 0)
+        verifyDisplay(
+                root.children[2], id = 3, width = 150f, height = 100f, POSITION_RIGHT, offset = 0f,
+                noOfChildren = 0)
+        verifyDisplay(
+                root.children[3], id = 4, width = 150f, height = 100f, POSITION_BOTTOM, offset = 0f,
+                noOfChildren = 0)
     }
 
     @Test
     fun rearrange_elbowArrangementDoesNotUseCornerAdjacency1() {
-        val nodes = rearrangeRects(
+        val root = rearrangeRects(
             //     2
             //     |
             // 0 - 1
@@ -469,20 +476,20 @@
             RectF(100f, -100f, 200f, 0f),
         )
 
-        assertThat(nodes[0].children).containsExactly(nodes[1])
-        assertThat(nodes[1].children).containsExactly(nodes[2])
-        assertThat(nodes[2].children).isEmpty()
-
-        assertPositioning(
-            nodes,
-            Pair(POSITION_RIGHT, 0f),
-            Pair(POSITION_TOP, 0f),
-        )
+        verifyDisplay(root, id = 0, width = 100f, height = 100f, noOfChildren = 1)
+        var node = root.children[0]
+        verifyDisplay(
+                node, id = 1, width = 100f, height = 100f, POSITION_RIGHT, offset = 0f,
+                noOfChildren = 1)
+        node = node.children[0]
+        verifyDisplay(
+                node, id = 2, width = 100f, height = 100f, POSITION_TOP,
+                offset = 0f, noOfChildren = 0)
     }
 
     @Test
     fun rearrange_elbowArrangementDoesNotUseCornerAdjacency2() {
-        val nodes = rearrangeRects(
+        val root = rearrangeRects(
             //     0
             //     |
             //     1
@@ -495,22 +502,24 @@
             RectF(-100f, 200f, 0f, 300f),
         )
 
-        assertThat(nodes[0].children).containsExactly(nodes[1])
-        assertThat(nodes[1].children).containsExactly(nodes[2])
-        assertThat(nodes[2].children).containsExactly(nodes[3])
-        assertThat(nodes[3].children).isEmpty()
-
-        assertPositioning(
-            nodes,
-            Pair(POSITION_BOTTOM, 0f),
-            Pair(POSITION_BOTTOM, 0f),
-            Pair(POSITION_LEFT, 0f),
-        )
+        verifyDisplay(root, id = 0, width = 100f, height = 100f, noOfChildren = 1)
+        var node = root.children[0]
+        verifyDisplay(
+                node, id = 1, width = 100f, height = 100f, POSITION_BOTTOM, offset = 0f,
+                noOfChildren = 1)
+        node = node.children[0]
+        verifyDisplay(
+                node, id = 2, width = 100f, height = 100f, POSITION_BOTTOM, offset = 0f,
+                noOfChildren = 1)
+        node = node.children[0]
+        verifyDisplay(
+                node, id = 3, width = 100f, height = 100f, POSITION_LEFT, offset = 0f,
+                noOfChildren = 0)
     }
 
     @Test
     fun rearrange_useLargerEdge() {
-        val nodes = rearrangeRects(
+        val root = rearrangeRects(
             // 444111
             // 444111
             // 444111
@@ -527,23 +536,24 @@
             RectF(0f, 0f, 30f, 30f),
         )
 
-        assertPositioning(
-            nodes,
-            Pair(POSITION_TOP, 10f),
-            Pair(POSITION_RIGHT, 0f),
-            Pair(POSITION_BOTTOM, -10f),
-            Pair(POSITION_LEFT, 0f),
-        )
-
-        assertThat(nodes[0].children).containsExactly(nodes[1], nodes[2])
-        assertThat(nodes[1].children).containsExactly(nodes[4])
-        assertThat(nodes[2].children).containsExactly(nodes[3])
-        (3..4).forEach { assertThat(nodes[it].children).isEmpty() }
+        verifyDisplay(root, id = 0, width = 30f, height = 30f, noOfChildren = 2)
+        verifyDisplay(
+                root.children[0], id = 1, width = 30f, height = 30f, POSITION_TOP,
+                offset = 10f, noOfChildren = 1)
+        verifyDisplay(
+                root.children[0].children[0], id = 4, width = 30f, height = 30f, POSITION_LEFT,
+                offset = 0f, noOfChildren = 0)
+        verifyDisplay(
+                root.children[1], id = 2, width = 30f, height = 30f, POSITION_RIGHT,
+                offset = 0f, noOfChildren = 1)
+        verifyDisplay(
+                root.children[1].children[0], id = 3, width = 30f, height = 30f, POSITION_BOTTOM,
+                offset = -10f, noOfChildren = 0)
     }
 
     @Test
     fun rearrange_closeGaps() {
-        val nodes = rearrangeRects(
+        val root = rearrangeRects(
             // 000
             // 000 111
             // 000 111
@@ -558,16 +568,14 @@
                                                             // TOP/BOTTOM attach
         )
 
-        assertPositioning(
-            nodes,
-            // In the case of corner adjacency, we prefer a left/right attachment.
-            Pair(POSITION_RIGHT, 10f),
-            Pair(POSITION_BOTTOM, 30f),
-        )
-
-        assertThat(nodes[0].children).containsExactly(nodes[1])
-        assertThat(nodes[1].children).containsExactly(nodes[2])
-        assertThat(nodes[2].children).isEmpty()
+        verifyDisplay(root, id = 0, width = 30f, height = 30f, noOfChildren = 1)
+        verifyDisplay(
+                root.children[0], id = 1, width = 30f, height = 30f, POSITION_RIGHT, offset = 10f,
+                noOfChildren = 1)
+        // In the case of corner adjacency, we prefer a left/right attachment.
+        verifyDisplay(
+                root.children[0].children[0], id = 2, width = 29.5f, height = 30f, POSITION_BOTTOM,
+                offset = 30f, noOfChildren = 0)
     }
 
     @Test
@@ -612,8 +620,10 @@
     /**
      * Runs the rearrange algorithm and returns the resulting tree as a list of nodes, with the
      * root at index 0. The number of nodes is inferred from the number of positions passed.
+     *
+     * Returns the root node.
      */
-    private fun rearrangeRects(vararg pos: RectF): List<DisplayTopology.TreeNode> {
+    private fun rearrangeRects(vararg pos: RectF): DisplayTopology.TreeNode {
         // Generates a linear sequence of nodes in order in the List from root to leaf,
         // left-to-right. IDs are ascending from 0 to count - 1.
 
@@ -631,7 +641,7 @@
             PointF(pos[it].left, pos[it].top)
         })
 
-        return nodes
+        return nodes[0]
     }
 
     private fun verifyDisplay(display: DisplayTopology.TreeNode, id: Int, width: Float,
@@ -644,11 +654,4 @@
         assertThat(display.offset).isEqualTo(offset)
         assertThat(display.children).hasSize(noOfChildren)
     }
-
-    private fun assertPositioning(
-            nodes: List<DisplayTopology.TreeNode>, vararg positions: Pair<Int, Float>) {
-        assertThat(nodes.drop(1).map { Pair(it.position, it.offset) })
-            .containsExactly(*positions)
-            .inOrder()
-    }
 }
diff --git a/core/tests/coretests/src/android/view/ViewGroupTest.java b/core/tests/coretests/src/android/view/ViewGroupTest.java
index 43c404e..ae3ad36 100644
--- a/core/tests/coretests/src/android/view/ViewGroupTest.java
+++ b/core/tests/coretests/src/android/view/ViewGroupTest.java
@@ -213,35 +213,6 @@
         assertTrue(autofillableViews.containsAll(Arrays.asList(viewA, viewC)));
     }
 
-    @Test
-    public void testMeasureCache() {
-        final int spec1 = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.AT_MOST);
-        final int spec2 = View.MeasureSpec.makeMeasureSpec(50, View.MeasureSpec.AT_MOST);
-        final Context context = getInstrumentation().getContext();
-        final View child = new View(context);
-        final TestView parent = new TestView(context, 0);
-        parent.addView(child);
-
-        child.setPadding(1, 2, 3, 4);
-        parent.measure(spec1, spec1);
-        assertEquals(4, parent.getMeasuredWidth());
-        assertEquals(6, parent.getMeasuredHeight());
-
-        child.setPadding(5, 6, 7, 8);
-        parent.measure(spec2, spec2);
-        assertEquals(12, parent.getMeasuredWidth());
-        assertEquals(14, parent.getMeasuredHeight());
-
-        // This ends the state of forceLayout.
-        parent.layout(0, 0, 50, 50);
-
-        // The cached values should be cleared after the new setPadding is called. And the measured
-        // width and height should be up-to-date.
-        parent.measure(spec1, spec1);
-        assertEquals(12, parent.getMeasuredWidth());
-        assertEquals(14, parent.getMeasuredHeight());
-    }
-
     private static void getUnobscuredTouchableRegion(Region outRegion, View view) {
         outRegion.set(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
         final ViewParent parent = view.getParent();
@@ -269,19 +240,6 @@
         protected void onLayout(boolean changed, int l, int t, int r, int b) {
             // We don't layout this view.
         }
-
-        @Override
-        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-            int measuredWidth = 0;
-            int measuredHeight = 0;
-            final int count = getChildCount();
-            for (int i = 0; i < count; i++) {
-                final View child = getChildAt(i);
-                measuredWidth += child.getPaddingLeft() + child.getPaddingRight();
-                measuredHeight += child.getPaddingTop() + child.getPaddingBottom();
-            }
-            setMeasuredDimension(measuredWidth, measuredHeight);
-        }
     }
 
     public static class AutofillableTestView extends TestView {
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
index 402b92a..26806b1 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
@@ -16,16 +16,23 @@
 
 package android.view.textclassifier;
 
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertThrows;
 import static org.mockito.Mockito.mock;
 
+import android.Manifest;
 import android.content.Context;
+import android.permission.flags.Flags;
+import android.platform.test.annotations.RequiresFlagsEnabled;
 
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -61,4 +68,28 @@
         assertThat(mTcm.getTextClassifier(TextClassifier.SYSTEM))
                 .isInstanceOf(SystemTextClassifier.class);
     }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+    public void testGetClassifier() {
+        Assume.assumeTrue(Flags.textClassifierChoiceApiEnabled());
+        assertThrows(SecurityException.class,
+                () -> mTcm.getClassifier(TextClassifier.CLASSIFIER_TYPE_DEVICE_DEFAULT));
+        assertThrows(SecurityException.class,
+                () -> mTcm.getClassifier(TextClassifier.CLASSIFIER_TYPE_ANDROID_DEFAULT));
+        assertThrows(SecurityException.class,
+                () -> mTcm.getClassifier(TextClassifier.CLASSIFIER_TYPE_SELF_PROVIDED));
+
+        runWithShellPermissionIdentity(() -> {
+            assertThat(
+                    mTcm.getClassifier(TextClassifier.CLASSIFIER_TYPE_DEVICE_DEFAULT)).isInstanceOf(
+                    SystemTextClassifier.class);
+            assertThat(mTcm.getClassifier(
+                    TextClassifier.CLASSIFIER_TYPE_ANDROID_DEFAULT)).isInstanceOf(
+                    SystemTextClassifier.class);
+            assertThat(mTcm.getClassifier(
+                    TextClassifier.CLASSIFIER_TYPE_SELF_PROVIDED)).isSameInstanceAs(
+                    TextClassifier.NO_OP);
+        }, Manifest.permission.ACCESS_TEXT_CLASSIFIER_BY_TYPE);
+    }
 }
diff --git a/core/tests/coretests/src/android/window/WindowContextTest.java b/core/tests/coretests/src/android/window/WindowContextTest.java
index 21930d1..b934426 100644
--- a/core/tests/coretests/src/android/window/WindowContextTest.java
+++ b/core/tests/coretests/src/android/window/WindowContextTest.java
@@ -33,7 +33,9 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.app.Activity;
 import android.app.EmptyActivity;
@@ -48,7 +50,9 @@
 import android.hardware.display.DisplayManager;
 import android.os.Binder;
 import android.os.IBinder;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.view.Display;
 import android.view.IWindowManager;
 import android.view.View;
@@ -64,6 +68,7 @@
 import androidx.test.rule.ActivityTestRule;
 
 import com.android.frameworks.coretests.R;
+import com.android.window.flags.Flags;
 
 import org.junit.After;
 import org.junit.Before;
@@ -91,6 +96,8 @@
     public ActivityTestRule<EmptyActivity> mActivityRule =
             new ActivityTestRule<>(EmptyActivity.class, false /* initialTouchMode */,
                     false /* launchActivity */);
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
 
     private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
     private final WindowContext mWindowContext = createWindowContext();
@@ -340,17 +347,35 @@
     }
 
     @Test
-    public void updateDisplay_wasAttached_detachThenAttachedPropagatedToTokenController() {
+    @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+    public void reparentToDisplayId_wasAttached_reparentToDisplayAreaPropagatedToTokenController() {
         final WindowTokenClientController mockWindowTokenClientController =
                 mock(WindowTokenClientController.class);
+        when(mockWindowTokenClientController.attachToDisplayArea(any(), anyInt(), anyInt(),
+                any())).thenReturn(true);
         WindowTokenClientController.overrideForTesting(mockWindowTokenClientController);
 
-        mWindowContext.updateDisplay(DEFAULT_DISPLAY + 1);
+        mWindowContext.reparentToDisplay(DEFAULT_DISPLAY + 1);
 
-        verify(mockWindowTokenClientController).detachIfNeeded(any());
-        verify(mockWindowTokenClientController).attachToDisplayArea(any(),
-                anyInt(), /* displayId= */ eq(DEFAULT_DISPLAY + 1),
-                any());
+        verify(mockWindowTokenClientController).reparentToDisplayArea(any(),
+                /* displayId= */ eq(DEFAULT_DISPLAY + 1)
+        );
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+    public void reparentToDisplayId_sameDisplayId_noReparenting() {
+        final WindowTokenClientController mockWindowTokenClientController =
+                mock(WindowTokenClientController.class);
+        when(mockWindowTokenClientController.attachToDisplayArea(any(), anyInt(), anyInt(),
+                any())).thenReturn(true);
+        WindowTokenClientController.overrideForTesting(mockWindowTokenClientController);
+
+        mWindowContext.reparentToDisplay(DEFAULT_DISPLAY);
+
+        verify(mockWindowTokenClientController, never()).reparentToDisplayArea(any(),
+                /* displayId= */ eq(DEFAULT_DISPLAY)
+        );
     }
 
     private WindowContext createWindowContext() {
diff --git a/core/tests/coretests/src/com/android/internal/view/ScrollCaptureInternalTest.java b/core/tests/coretests/src/com/android/internal/view/ScrollCaptureInternalTest.java
new file mode 100644
index 0000000..5f6d806
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/view/ScrollCaptureInternalTest.java
@@ -0,0 +1,243 @@
+/*
+ * 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.internal.view;
+
+import static android.view.flags.Flags.FLAG_SCROLL_CAPTURE_RELAX_SCROLL_VIEW_CRITERIA;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static com.android.internal.view.ScrollCaptureInternal.TYPE_FIXED;
+import static com.android.internal.view.ScrollCaptureInternal.TYPE_OPAQUE;
+import static com.android.internal.view.ScrollCaptureInternal.TYPE_RECYCLING;
+import static com.android.internal.view.ScrollCaptureInternal.TYPE_SCROLLING;
+import static com.android.internal.view.ScrollCaptureInternal.detectScrollingType;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.testing.AndroidTestingRunner;
+import android.view.ViewGroup;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests scrolling detection.
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class ScrollCaptureInternalTest {
+
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+    /**
+     * Tests the effect of padding on scroll capture search dispatch.
+     * <p>
+     * Verifies computation of child visible bounds with padding.
+     */
+    @Test
+    public void testDetectScrollingType_scrolling_notScrollable() {
+        MockScrollable scrollable = new MockScrollable.Builder()
+                .bounds(0, 0, 200, 200)
+                .childCount(1)
+                .canScrollUp(false)
+                .canScrollDown(false)
+                .scrollToEnabled(false)
+                .build(getInstrumentation().getContext());
+
+        assertEquals(TYPE_FIXED, detectScrollingType(scrollable));
+    }
+
+    @Test
+    public void testDetectScrollingType_scrolling_noChildren() {
+        MockScrollable scrollable = new MockScrollable.Builder()
+                .bounds(0, 0, 200, 200)
+                .childCount(0)
+                .canScrollUp(false)
+                .canScrollDown(true)
+                .scrollToEnabled(true)
+                .build(getInstrumentation().getContext());
+
+        assertEquals(TYPE_OPAQUE, detectScrollingType(scrollable));
+    }
+
+    @Test
+    public void testDetectScrollingType_scrolling() {
+        MockScrollable scrollable = new MockScrollable.Builder()
+                .bounds(0, 0, 200, 200)
+                .childCount(1)
+                .canScrollUp(false)
+                .canScrollDown(true)
+                .scrollToEnabled(true)
+                .build(getInstrumentation().getContext());
+
+        assertEquals(TYPE_SCROLLING, detectScrollingType(scrollable));
+    }
+
+    @Test
+    public void testDetectScrollingType_scrolling_partiallyScrolled() {
+        MockScrollable scrollable = new MockScrollable.Builder()
+                .bounds(0, 0, 200, 200)
+                .childCount(1)
+                .canScrollUp(true)
+                .canScrollDown(true)
+                .scrollToEnabled(true)
+                .build(getInstrumentation().getContext());
+        scrollable.scrollTo(0, 100);
+
+        assertEquals(TYPE_SCROLLING, detectScrollingType(scrollable));
+    }
+
+    @Test
+    @EnableFlags(FLAG_SCROLL_CAPTURE_RELAX_SCROLL_VIEW_CRITERIA)
+    public void testDetectScrollingType_scrolling_multipleChildren() {
+        MockScrollable scrollable = new MockScrollable.Builder()
+                .bounds(0, 0, 200, 200)
+                .childCount(10)
+                .canScrollUp(false)
+                .canScrollDown(true)
+                .scrollToEnabled(true)
+                .build(getInstrumentation().getContext());
+
+        assertEquals(TYPE_SCROLLING, detectScrollingType(scrollable));
+    }
+
+    @Test
+    public void testDetectScrollingType_recycling() {
+        MockScrollable scrollable = new MockScrollable.Builder()
+                .bounds(0, 0, 200, 200)
+                .childCount(10)
+                .canScrollUp(false)
+                .canScrollDown(true)
+                .scrollToEnabled(false)
+                .build(getInstrumentation().getContext());
+
+        assertEquals(TYPE_RECYCLING, detectScrollingType(scrollable));
+    }
+
+    @Test
+    public void testDetectScrollingType_noChildren() {
+        MockScrollable scrollable = new MockScrollable.Builder()
+                .bounds(0, 0, 200, 200)
+                .childCount(0)
+                .canScrollUp(true)
+                .canScrollDown(true)
+                .scrollToEnabled(false)
+                .build(getInstrumentation().getContext());
+
+        assertEquals(TYPE_OPAQUE, detectScrollingType(scrollable));
+    }
+
+
+    /**
+     * A mock which can exhibit some attributes and behaviors used to detect different types
+     * of scrolling content.
+     */
+    private static class MockScrollable extends ViewGroup {
+        private final int mChildCount;
+        private final boolean mCanScrollUp;
+        private final boolean mCanScrollDown;
+        private final boolean mScrollToEnabled;
+
+        MockScrollable(Context context, Rect bounds, int childCount, boolean canScrollUp,
+                boolean canScrollDown, boolean scrollToEnabled) {
+            super(context);
+            setFrame(bounds.left, bounds.top, bounds.right, bounds.bottom);
+            mCanScrollUp = canScrollUp;
+            mCanScrollDown = canScrollDown;
+            mScrollToEnabled = scrollToEnabled;
+            mChildCount = childCount;
+        }
+
+        private static class Builder {
+            private int mChildCount;
+            private boolean mCanScrollUp;
+            private boolean mCanScrollDown;
+            private boolean mScrollToEnabled = true;
+
+            private final Rect mBounds = new Rect();
+
+            public MockScrollable build(Context context) {
+                return new MockScrollable(context,
+                        mBounds, mChildCount, mCanScrollUp, mCanScrollDown,
+                        mScrollToEnabled);
+            }
+
+            public Builder canScrollUp(boolean canScrollUp) {
+                mCanScrollUp = canScrollUp;
+                return this;
+            }
+
+            public Builder canScrollDown(boolean canScrollDown) {
+                mCanScrollDown = canScrollDown;
+                return this;
+            }
+
+            public Builder scrollToEnabled(boolean enabled) {
+                mScrollToEnabled = enabled;
+                return this;
+            }
+
+            public Builder childCount(int childCount) {
+                mChildCount = childCount;
+                return this;
+            }
+
+            public Builder bounds(int left, int top, int right, int bottom) {
+                mBounds.set(left, top, right, bottom);
+                return this;
+            }
+        }
+
+        @Override
+        public boolean canScrollVertically(int direction) {
+            if (direction > 0) {
+                return mCanScrollDown;
+            } else if (direction < 0) {
+                return mCanScrollUp;
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public int getChildCount() {
+            return mChildCount;
+        }
+
+        @Override
+        public void scrollTo(int x, int y) {
+            if (mScrollToEnabled) {
+                super.scrollTo(x, y);
+            }
+        }
+
+        @Override
+        protected void onLayout(boolean changed, int l, int t, int r, int b) {
+            // We don't layout this view.
+        }
+    }
+}
diff --git a/core/tests/overlaytests/device_self_targeting/Android.bp b/core/tests/overlaytests/device_self_targeting/Android.bp
index 931eac5..14a3cdf 100644
--- a/core/tests/overlaytests/device_self_targeting/Android.bp
+++ b/core/tests/overlaytests/device_self_targeting/Android.bp
@@ -31,6 +31,7 @@
         "androidx.test.ext.junit",
         "mockito-target-minus-junit4",
         "truth",
+        "flag-junit",
     ],
 
     optimize: {
diff --git a/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java b/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
index 28d6545..bcf1446 100644
--- a/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
+++ b/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
@@ -16,6 +16,7 @@
 
 package com.android.overlaytest;
 
+import static android.content.res.Flags.FLAG_SELF_TARGETING_ANDROID_RESOURCE_FRRO;
 import static android.content.Context.MODE_PRIVATE;
 import static android.content.pm.PackageManager.SIGNATURE_NO_MATCH;
 
@@ -41,6 +42,8 @@
 import android.os.FabricatedOverlayInternalEntry;
 import android.os.ParcelFileDescriptor;
 import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.util.Log;
 import android.util.Pair;
 import android.util.TypedValue;
@@ -76,6 +79,8 @@
  */
 @RunWith(AndroidJUnit4.class)
 public class OverlayManagerImplTest {
+    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     private static final String TAG = "OverlayManagerImplTest";
 
     private static final String TARGET_COLOR_RES = "color/mycolor";
@@ -210,6 +215,22 @@
     }
 
     @Test
+    @DisableFlags(FLAG_SELF_TARGETING_ANDROID_RESOURCE_FRRO)
+    public void registerOverlay_forAndroidPackage_shouldFail() {
+        FabricatedOverlayInternal overlayInternal =
+                createOverlayWithName(
+                        mOverlayName,
+                        SYSTEM_APP_OVERLAYABLE,
+                        "android",
+                        List.of(Pair.create("color/white", Pair.create(null, Color.BLACK))));
+
+        assertThrows(
+                "Wrong target package name",
+                IllegalArgumentException.class,
+                () -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
+    }
+
+    @Test
     public void getOverlayInfosForTarget_defaultShouldBeZero() {
         List<OverlayInfo> overlayInfos =
                 mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName());
diff --git a/core/tests/overlaytests/host/Android.bp b/core/tests/overlaytests/host/Android.bp
index 6340980..9b72004 100644
--- a/core/tests/overlaytests/host/Android.bp
+++ b/core/tests/overlaytests/host/Android.bp
@@ -28,14 +28,14 @@
     test_suites: [
         "device-tests",
     ],
-    target_required: [
-        "OverlayHostTests_NonPlatformSignatureOverlay",
-        "OverlayHostTests_PlatformSignatureStaticOverlay",
-        "OverlayHostTests_PlatformSignatureOverlay",
-        "OverlayHostTests_UpdateOverlay",
-        "OverlayHostTests_FrameworkOverlayV1",
-        "OverlayHostTests_FrameworkOverlayV2",
-        "OverlayHostTests_AppOverlayV1",
-        "OverlayHostTests_AppOverlayV2",
+    device_common_data: [
+        ":OverlayHostTests_NonPlatformSignatureOverlay",
+        ":OverlayHostTests_PlatformSignatureStaticOverlay",
+        ":OverlayHostTests_PlatformSignatureOverlay",
+        ":OverlayHostTests_UpdateOverlay",
+        ":OverlayHostTests_FrameworkOverlayV1",
+        ":OverlayHostTests_FrameworkOverlayV2",
+        ":OverlayHostTests_AppOverlayV1",
+        ":OverlayHostTests_AppOverlayV2",
     ],
 }
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index a26f5e3..5c706b2 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -419,6 +419,7 @@
         <permission name="android.permission.REQUEST_COMPANION_PROFILE_APP_STREAMING" />
         <permission name="android.permission.REQUEST_COMPANION_PROFILE_WATCH" />
         <permission name="android.permission.REQUEST_COMPANION_PROFILE_NEARBY_DEVICE_STREAMING" />
+        <permission name="android.permission.REQUEST_COMPANION_PROFILE_SENSOR_DEVICE_STREAMING" />
         <permission name="android.permission.REQUEST_COMPANION_PROFILE_COMPUTER" />
         <permission name="android.permission.REQUEST_COMPANION_SELF_MANAGED" />
         <permission name="android.permission.REQUEST_OBSERVE_DEVICE_UUID_PRESENCE" />
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 9bf4d65..2e88514 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -34,6 +34,7 @@
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.EnabledSince;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.graphics.fonts.FontStyle;
 import android.graphics.fonts.FontVariationAxis;
 import android.graphics.text.TextRunShaper;
 import android.os.Build;
@@ -2141,6 +2142,14 @@
      * @see FontVariationAxis
      */
     public boolean setFontVariationSettings(String fontVariationSettings) {
+        return setFontVariationSettings(fontVariationSettings, 0 /* wght adjust */);
+    }
+
+    /**
+     * Set font variation settings with weight adjustment
+     * @hide
+     */
+    public boolean setFontVariationSettings(String fontVariationSettings, int wghtAdjust) {
         final boolean useFontVariationStore = Flags.typefaceRedesignReadonly()
                 && CompatChanges.isChangeEnabled(NEW_FONT_VARIATION_MANAGEMENT);
         if (useFontVariationStore) {
@@ -2154,8 +2163,13 @@
 
             long builderPtr = nCreateFontVariationBuilder(axes.length);
             for (int i = 0; i < axes.length; ++i) {
-                nAddFontVariationToBuilder(builderPtr, axes[i].getOpenTypeTagValue(),
-                        axes[i].getStyleValue());
+                int tag = axes[i].getOpenTypeTagValue();
+                float value = axes[i].getStyleValue();
+                if (tag == 0x77676874 /* wght */) {
+                    value = Math.clamp(value + wghtAdjust,
+                            FontStyle.FONT_WEIGHT_MIN, FontStyle.FONT_WEIGHT_MAX);
+                }
+                nAddFontVariationToBuilder(builderPtr, tag, value);
             }
             nSetFontVariationOverride(mNativePaint, builderPtr);
             mFontVariationSettings = fontVariationSettings;
diff --git a/libs/WindowManager/Shell/aconfig/multitasking.aconfig b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
index 714d5e0..5f1fb4b 100644
--- a/libs/WindowManager/Shell/aconfig/multitasking.aconfig
+++ b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
@@ -132,13 +132,6 @@
 }
 
 flag {
-    name: "enable_bubble_bar_in_persistent_task_bar"
-    namespace: "multitasking"
-    description: "Enable bubble bar to be shown in the persistent task bar"
-    bug: "346391377"
-}
-
-flag {
     name: "bubble_view_info_executors"
     namespace: "multitasking"
     description: "Use executors to inflate bubble views"
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
index b38d00da..1d0c505 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
@@ -602,8 +602,72 @@
         testGetBubbleBarExpandedViewBounds(onLeft = false, isOverflow = true)
     }
 
+    @Test
+    fun getExpandedViewContainerPadding_largeScreen_fitsMaxViewWidth() {
+        val expandedViewWidth = context.resources.getDimensionPixelSize(
+            R.dimen.bubble_expanded_view_largescreen_width
+        )
+        // set the screen size so that it is wide enough to fit the maximum width size
+        val screenWidth = expandedViewWidth * 2
+        positioner.update(
+            defaultDeviceConfig.copy(
+                windowBounds = Rect(0, 0, screenWidth, 2000),
+                isLargeScreen = true,
+                isLandscape = false
+            )
+        )
+        val paddings =
+            positioner.getExpandedViewContainerPadding(/* onLeft= */ true, /* isOverflow= */ false)
+
+        val padding = context.resources.getDimensionPixelSize(
+            R.dimen.bubble_expanded_view_largescreen_landscape_padding
+        )
+        val right = screenWidth - expandedViewWidth - padding
+        assertThat(paddings).isEqualTo(intArrayOf(padding - positioner.pointerSize, 0, right, 0))
+    }
+
+    @Test
+    fun getExpandedViewContainerPadding_largeScreen_doesNotFitMaxViewWidth() {
+        positioner.update(
+            defaultDeviceConfig.copy(
+                windowBounds = Rect(0, 0, 600, 2000),
+                isLargeScreen = true,
+                isLandscape = false
+            )
+        )
+        val paddings =
+            positioner.getExpandedViewContainerPadding(/* onLeft= */ true, /* isOverflow= */ false)
+
+        val padding = context.resources.getDimensionPixelSize(
+            R.dimen.bubble_expanded_view_largescreen_landscape_padding
+        )
+        // the screen is not wide enough to fit the maximum width size, so the view fills the screen
+        // minus left and right padding
+        assertThat(paddings).isEqualTo(intArrayOf(padding - positioner.pointerSize, 0, padding, 0))
+    }
+
+    @Test
+    fun getExpandedViewContainerPadding_smallTablet() {
+        val screenWidth = 500
+        positioner.update(
+            defaultDeviceConfig.copy(
+                windowBounds = Rect(0, 0, screenWidth, 2000),
+                isLargeScreen = true,
+                isSmallTablet = true,
+                isLandscape = false
+            )
+        )
+        val paddings =
+            positioner.getExpandedViewContainerPadding(/* onLeft= */ true, /* isOverflow= */ false)
+
+        // for small tablets, the view width is set to be 0.72 * screen width
+        val viewWidth = (screenWidth * 0.72).toInt()
+        val padding = (screenWidth - viewWidth) / 2
+        assertThat(paddings).isEqualTo(intArrayOf(padding - positioner.pointerSize, 0, padding, 0))
+    }
+
     private fun testGetBubbleBarExpandedViewBounds(onLeft: Boolean, isOverflow: Boolean) {
-        positioner.setShowingInBubbleBar(true)
+        positioner.isShowingInBubbleBar = true
         val windowBounds = Rect(0, 0, 2000, 2600)
         val insets = Insets.of(10, 20, 5, 15)
         val deviceConfig =
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt
new file mode 100644
index 0000000..0d8f809
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt
@@ -0,0 +1,228 @@
+/*
+ * 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.ViewGroup
+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.getInstrumentation
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.TestShellExecutor
+import com.android.wm.shell.bubbles.Bubble
+import com.android.wm.shell.bubbles.BubbleExpandedViewManager
+import com.android.wm.shell.bubbles.BubbleLogger
+import com.android.wm.shell.bubbles.BubbleOverflow
+import com.android.wm.shell.bubbles.BubblePositioner
+import com.android.wm.shell.bubbles.DeviceConfig
+import com.android.wm.shell.bubbles.FakeBubbleExpandedViewManager
+import com.android.wm.shell.bubbles.FakeBubbleFactory
+import com.android.wm.shell.bubbles.FakeBubbleTaskViewFactory
+import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.Semaphore
+import java.util.concurrent.TimeUnit
+import org.junit.After
+import org.junit.Before
+import org.junit.ClassRule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** Tests for [BubbleBarAnimationHelper] */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class BubbleBarAnimationHelperTest {
+
+    companion object {
+        @JvmField @ClassRule val animatorTestRule: AnimatorTestRule = AnimatorTestRule()
+
+        const val SCREEN_WIDTH = 2000
+        const val SCREEN_HEIGHT = 1000
+    }
+
+    private val context = ApplicationProvider.getApplicationContext<Context>()
+
+    private lateinit var animationHelper: BubbleBarAnimationHelper
+    private lateinit var bubblePositioner: BubblePositioner
+    private lateinit var expandedViewManager: BubbleExpandedViewManager
+    private lateinit var bubbleLogger: BubbleLogger
+    private lateinit var mainExecutor: TestShellExecutor
+    private lateinit var bgExecutor: TestShellExecutor
+    private lateinit var container: FrameLayout
+
+    @Before
+    fun setUp() {
+        ProtoLog.REQUIRE_PROTOLOGTOOL = false
+        ProtoLog.init()
+        val windowManager = context.getSystemService(WindowManager::class.java)
+        bubblePositioner = BubblePositioner(context, windowManager)
+        bubblePositioner.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),
+            )
+        bubblePositioner.update(deviceConfig)
+        expandedViewManager = FakeBubbleExpandedViewManager()
+        bubbleLogger = BubbleLogger(UiEventLoggerFake())
+
+        mainExecutor = TestShellExecutor()
+        bgExecutor = TestShellExecutor()
+
+        container = FrameLayout(context)
+
+        animationHelper = BubbleBarAnimationHelper(context, bubblePositioner)
+    }
+
+    @After
+    fun tearDown() {
+        bgExecutor.flushAll()
+        mainExecutor.flushAll()
+    }
+
+    @Test
+    fun animateSwitch_bubbleToBubble_oldHiddenNewShown() {
+        val fromBubble = createBubble(key = "from").initialize(container)
+        val toBubble = createBubble(key = "to").initialize(container)
+
+        val semaphore = Semaphore(0)
+        val after = Runnable { semaphore.release() }
+
+        getInstrumentation().runOnMainSync {
+            animationHelper.animateSwitch(fromBubble, toBubble, after)
+            animatorTestRule.advanceTimeBy(1000)
+        }
+        getInstrumentation().waitForIdleSync()
+
+        assertThat(semaphore.tryAcquire(5, TimeUnit.SECONDS)).isTrue()
+        assertThat(fromBubble.bubbleBarExpandedView?.visibility).isEqualTo(View.INVISIBLE)
+        assertThat(fromBubble.bubbleBarExpandedView?.alpha).isEqualTo(0f)
+        assertThat(fromBubble.bubbleBarExpandedView?.isSurfaceZOrderedOnTop).isFalse()
+
+        assertThat(toBubble.bubbleBarExpandedView?.visibility).isEqualTo(View.VISIBLE)
+        assertThat(toBubble.bubbleBarExpandedView?.alpha).isEqualTo(1f)
+        assertThat(toBubble.bubbleBarExpandedView?.isSurfaceZOrderedOnTop).isFalse()
+    }
+
+    @Test
+    fun animateSwitch_bubbleToBubble_handleColorTransferred() {
+        val fromBubble = createBubble(key = "from").initialize(container)
+        fromBubble.bubbleBarExpandedView!!
+            .handleView
+            .updateHandleColor(/* isRegionDark= */ true, /* animated= */ false)
+        val toBubble = createBubble(key = "to").initialize(container)
+
+        getInstrumentation().runOnMainSync {
+            animationHelper.animateSwitch(fromBubble, toBubble, /* afterAnimation= */ null)
+            animatorTestRule.advanceTimeBy(1000)
+        }
+        getInstrumentation().waitForIdleSync()
+
+        assertThat(toBubble.bubbleBarExpandedView!!.handleView.handleColor)
+            .isEqualTo(fromBubble.bubbleBarExpandedView!!.handleView.handleColor)
+    }
+
+    @Test
+    fun animateSwitch_bubbleToOverflow_oldHiddenNewShown() {
+        val fromBubble = createBubble(key = "from").initialize(container)
+        val overflow = createOverflow().initialize(container)
+
+        val semaphore = Semaphore(0)
+        val after = Runnable { semaphore.release() }
+
+        getInstrumentation().runOnMainSync {
+            animationHelper.animateSwitch(fromBubble, overflow, after)
+            animatorTestRule.advanceTimeBy(1000)
+        }
+        getInstrumentation().waitForIdleSync()
+
+        assertThat(semaphore.tryAcquire(5, TimeUnit.SECONDS)).isTrue()
+        assertThat(fromBubble.bubbleBarExpandedView?.visibility).isEqualTo(View.INVISIBLE)
+        assertThat(fromBubble.bubbleBarExpandedView?.alpha).isEqualTo(0f)
+        assertThat(fromBubble.bubbleBarExpandedView?.isSurfaceZOrderedOnTop).isFalse()
+
+        assertThat(overflow.bubbleBarExpandedView?.visibility).isEqualTo(View.VISIBLE)
+        assertThat(overflow.bubbleBarExpandedView?.alpha).isEqualTo(1f)
+    }
+
+    @Test
+    fun animateSwitch_overflowToBubble_oldHiddenNewShown() {
+        val overflow = createOverflow().initialize(container)
+        val toBubble = createBubble(key = "to").initialize(container)
+
+        val semaphore = Semaphore(0)
+        val after = Runnable { semaphore.release() }
+
+        getInstrumentation().runOnMainSync {
+            animationHelper.animateSwitch(overflow, toBubble, after)
+            animatorTestRule.advanceTimeBy(1000)
+        }
+        getInstrumentation().waitForIdleSync()
+
+        assertThat(semaphore.tryAcquire(5, TimeUnit.SECONDS)).isTrue()
+        assertThat(overflow.bubbleBarExpandedView?.visibility).isEqualTo(View.INVISIBLE)
+        assertThat(overflow.bubbleBarExpandedView?.alpha).isEqualTo(0f)
+
+        assertThat(toBubble.bubbleBarExpandedView?.visibility).isEqualTo(View.VISIBLE)
+        assertThat(toBubble.bubbleBarExpandedView?.alpha).isEqualTo(1f)
+        assertThat(toBubble.bubbleBarExpandedView?.isSurfaceZOrderedOnTop).isFalse()
+    }
+
+    private fun createBubble(key: String): Bubble {
+        val bubbleBarExpandedView =
+            FakeBubbleFactory.createExpandedView(
+                context,
+                bubblePositioner,
+                expandedViewManager,
+                FakeBubbleTaskViewFactory(context, mainExecutor).create(),
+                mainExecutor,
+                bgExecutor,
+                bubbleLogger,
+            )
+        val viewInfo = FakeBubbleFactory.createViewInfo(bubbleBarExpandedView)
+        return FakeBubbleFactory.createChatBubble(context, key, viewInfo)
+    }
+
+    private fun createOverflow(): BubbleOverflow {
+        val overflow = BubbleOverflow(context, bubblePositioner)
+        overflow.initializeForBubbleBar(expandedViewManager, bubblePositioner, bubbleLogger)
+        return overflow
+    }
+
+    private fun Bubble.initialize(container: ViewGroup): Bubble {
+        getInstrumentation().runOnMainSync { container.addView(bubbleBarExpandedView) }
+        // Mark taskView's visible
+        bubbleBarExpandedView!!.onContentVisibilityChanged(true)
+        return this
+    }
+
+    private fun BubbleOverflow.initialize(container: ViewGroup): BubbleOverflow {
+        getInstrumentation().runOnMainSync { container.addView(bubbleBarExpandedView) }
+        return this
+    }
+}
diff --git a/libs/WindowManager/Shell/res/color/bubble_drop_target_background_color.xml b/libs/WindowManager/Shell/res/color/bubble_drop_target_background_color.xml
index ab1ab98..87d3628 100644
--- a/libs/WindowManager/Shell/res/color/bubble_drop_target_background_color.xml
+++ b/libs/WindowManager/Shell/res/color/bubble_drop_target_background_color.xml
@@ -16,5 +16,5 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <item android:alpha="0.35" android:color="?androidprv:attr/materialColorPrimaryContainer" />
+    <item android:alpha="0.35" android:color="@androidprv:color/materialColorPrimaryContainer" />
 </selector>
\ No newline at end of file
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 640d184..047f22f 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
@@ -22,5 +22,5 @@
         android:color="?androidprv:attr/colorAccentPrimary"/>
     <item android:state_selected="true"
         android:color="?androidprv:attr/colorAccentPrimary"/>
-    <item android:color="?androidprv:attr/materialColorOutlineVariant"/>
+    <item android:color="@androidprv:color/materialColorOutlineVariant"/>
 </selector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/color/open_by_default_settings_dialog_radio_button_color.xml b/libs/WindowManager/Shell/res/color/open_by_default_settings_dialog_radio_button_color.xml
index 0f9b28a..9741b94 100644
--- a/libs/WindowManager/Shell/res/color/open_by_default_settings_dialog_radio_button_color.xml
+++ b/libs/WindowManager/Shell/res/color/open_by_default_settings_dialog_radio_button_color.xml
@@ -17,6 +17,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
     <item android:state_checked="true"
-        android:color="?androidprv:attr/materialColorPrimaryContainer"/>
-    <item android:color="?androidprv:attr/materialColorSurfaceContainer"/>
+        android:color="@androidprv:color/materialColorPrimaryContainer"/>
+    <item android:color="@androidprv:color/materialColorSurfaceContainer"/>
 </selector>
diff --git a/libs/WindowManager/Shell/res/drawable/bubble_drop_target_background.xml b/libs/WindowManager/Shell/res/drawable/bubble_drop_target_background.xml
index b928a0b..20e00e1 100644
--- a/libs/WindowManager/Shell/res/drawable/bubble_drop_target_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/bubble_drop_target_background.xml
@@ -21,6 +21,6 @@
         <solid android:color="@color/bubble_drop_target_background_color" />
         <stroke
             android:width="1dp"
-            android:color="?androidprv:attr/materialColorPrimaryContainer" />
+            android:color="@androidprv:color/materialColorPrimaryContainer" />
     </shape>
 </inset>
diff --git a/libs/WindowManager/Shell/res/drawable/bubble_manage_btn_bg.xml b/libs/WindowManager/Shell/res/drawable/bubble_manage_btn_bg.xml
index 657720e..5acca45 100644
--- a/libs/WindowManager/Shell/res/drawable/bubble_manage_btn_bg.xml
+++ b/libs/WindowManager/Shell/res/drawable/bubble_manage_btn_bg.xml
@@ -19,7 +19,7 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:shape="rectangle">
     <solid
-        android:color="?androidprv:attr/materialColorSurfaceContainerHigh"
+        android:color="@androidprv:color/materialColorSurfaceContainerHigh"
         />
     <corners android:radius="18sp" />
 
diff --git a/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_bg.xml b/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_bg.xml
index 8fd2e68..f4d1de8 100644
--- a/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_bg.xml
+++ b/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_bg.xml
@@ -17,7 +17,7 @@
 <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="?androidprv:attr/materialColorSurfaceBright" />
+    <solid android:color="@androidprv:color/materialColorSurfaceBright" />
     <corners
         android:bottomLeftRadius="?android:attr/dialogCornerRadius"
         android:topLeftRadius="?android:attr/dialogCornerRadius"
diff --git a/libs/WindowManager/Shell/res/drawable/decor_desktop_mode_immersive_button_dark.xml b/libs/WindowManager/Shell/res/drawable/decor_desktop_mode_immersive_button_dark.xml
deleted file mode 100644
index f3800e0..0000000
--- a/libs/WindowManager/Shell/res/drawable/decor_desktop_mode_immersive_button_dark.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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.
-  -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:height="24dp"
-    android:width="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-    <path
-        android:fillColor="#000000"
-        android:pathData="M5,5H10V7H7V10H5V5M14,5H19V10H17V7H14V5M17,14H19V19H14V17H17V14M10,17V19H5V14H7V17H10Z"/>
-</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/decor_desktop_mode_immersive_exit_button_dark.xml b/libs/WindowManager/Shell/res/drawable/decor_desktop_mode_immersive_exit_button_dark.xml
deleted file mode 100644
index 5260450..0000000
--- a/libs/WindowManager/Shell/res/drawable/decor_desktop_mode_immersive_exit_button_dark.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?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.
-  -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="960"
-    android:viewportHeight="960"
-    android:tint="?attr/colorControlNormal">
-    <path
-        android:fillColor="@android:color/white"
-        android:pathData="M240,840L240,720L120,720L120,640L320,640L320,840L240,840ZM640,840L640,640L840,640L840,720L720,720L720,840L640,840ZM120,320L120,240L240,240L240,120L320,120L320,320L120,320ZM640,320L640,120L720,120L720,240L840,240L840,320L640,320Z"/>
-</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/decor_desktop_mode_immersive_or_maximize_exit_button_dark.xml b/libs/WindowManager/Shell/res/drawable/decor_desktop_mode_immersive_or_maximize_exit_button_dark.xml
new file mode 100644
index 0000000..b6289e2
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/decor_desktop_mode_immersive_or_maximize_exit_button_dark.xml
@@ -0,0 +1,26 @@
+<?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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="960"
+    android:viewportHeight="960"
+    android:tint="?attr/colorControlNormal">
+    <path
+        android:fillColor="@android:color/black"
+        android:pathData="M520,560L600,560L600,560ZM320,720Q287,720 263.5,696.5Q240,673 240,640L240,160Q240,127 263.5,103.5Q287,80 320,80L800,80Q833,80 856.5,103.5Q880,127 880,160L880,640Q880,673 856.5,696.5Q833,720 800,720L320,720ZM320,640L800,640Q800,640 800,640Q800,640 800,640L800,160Q800,160 800,160Q800,160 800,160L320,160Q320,160 320,160Q320,160 320,160L320,640Q320,640 320,640Q320,640 320,640ZM160,880Q127,880 103.5,856.5Q80,833 80,800L80,240L160,240L160,800Q160,800 160,800Q160,800 160,800L720,800L720,880L160,880ZM320,160L320,160Q320,160 320,160Q320,160 320,160L320,640Q320,640 320,640Q320,640 320,640L320,640Q320,640 320,640Q320,640 320,640L320,160Q320,160 320,160Q320,160 320,160Z"/>
+</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_handle_menu_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_handle_menu_background.xml
index 15837ad..5769a85 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_handle_menu_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_handle_menu_background.xml
@@ -18,5 +18,5 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
     <corners android:radius="@dimen/desktop_mode_handle_menu_corner_radius" />
-    <solid android:color="?androidprv:attr/materialColorSurfaceBright" />
+    <solid android:color="@androidprv:color/materialColorSurfaceBright" />
 </shape>
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_background.xml
index 9566f2f..bab2c95 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_background.xml
@@ -17,6 +17,6 @@
 <shape android:shape="rectangle"
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <solid android:color="?androidprv:attr/materialColorSurfaceContainerLow" />
+    <solid android:color="@androidprv:color/materialColorSurfaceContainerLow" />
     <corners android:radius="@dimen/desktop_mode_maximize_menu_corner_radius" />
 </shape>
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_layout_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_layout_background.xml
index a30cfb7..b03b134 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_layout_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_layout_background.xml
@@ -20,6 +20,6 @@
     android:shape="rectangle">
     <corners
         android:radius="@dimen/desktop_mode_maximize_menu_buttons_outline_radius"/>
-    <solid android:color="?androidprv:attr/materialColorSurfaceContainerLow"/>
-    <stroke android:width="1dp" android:color="?androidprv:attr/materialColorOutlineVariant"/>
+    <solid android:color="@androidprv:color/materialColorSurfaceContainerLow"/>
+    <stroke android:width="1dp" android:color="@androidprv:color/materialColorOutlineVariant"/>
 </shape>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_windowing_education_promo_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_windowing_education_promo_background.xml
index 645d24d..b24d432 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_windowing_education_promo_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_windowing_education_promo_background.xml
@@ -17,6 +17,6 @@
 <shape android:shape="rectangle"
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <solid android:color="?androidprv:attr/materialColorSurfaceContainerLow" />
+    <solid android:color="@androidprv:color/materialColorSurfaceContainerLow" />
     <corners android:radius="@dimen/desktop_windowing_education_promo_corner_radius" />
 </shape>
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_windowing_transition_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_windowing_transition_background.xml
index 4e673e6..dd1a1b1 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_windowing_transition_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_windowing_transition_background.xml
@@ -18,7 +18,7 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
     <item android:id="@+id/indicator_solid">
         <shape android:shape="rectangle">
-            <solid android:color="?androidprv:attr/materialColorPrimaryContainer" />
+            <solid android:color="@androidprv:color/materialColorPrimaryContainer" />
             <corners android:radius="28dp" />
         </shape>
     </item>
@@ -26,7 +26,7 @@
         <shape android:shape="rectangle">
             <corners android:radius="28dp" />
             <stroke android:width="1dp"
-                android:color="?androidprv:attr/materialColorPrimaryContainer"/>
+                android:color="@androidprv:color/materialColorPrimaryContainer"/>
         </shape>
     </item>
 </layer-list>
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_dialog_background.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_dialog_background.xml
index f37fb8d..527cc31 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_education_dialog_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_dialog_background.xml
@@ -17,6 +17,6 @@
 <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="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+    <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh"/>
     <corners android:radius="@dimen/letterbox_education_dialog_corner_radius"/>
 </shape>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml
index 3fdd059..5336b3a 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml
@@ -32,7 +32,7 @@
         </item>
         <item>
             <shape android:shape="rectangle">
-                <solid android:color="?androidprv:attr/materialColorPrimary"/>
+                <solid android:color="@androidprv:color/materialColorPrimary"/>
                 <corners android:radius="@dimen/letterbox_education_dialog_button_radius"/>
                 <padding android:left="@dimen/letterbox_education_dialog_horizontal_padding"
                          android:top="@dimen/letterbox_education_dialog_vertical_padding"
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_light_bulb.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_light_bulb.xml
index 67929df..f45d704 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_light_bulb.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_light_bulb.xml
@@ -25,6 +25,6 @@
             android:pathData="M0,0h32v32h-32z"/>
         <path
             android:pathData="M5.867,22.667C4.489,21.844 3.389,20.733 2.567,19.333C1.744,17.933 1.333,16.378 1.333,14.667C1.333,12.067 2.233,9.867 4.033,8.067C5.856,6.244 8.067,5.333 10.667,5.333C13.267,5.333 15.467,6.244 17.267,8.067C19.089,9.867 20,12.067 20,14.667C20,16.378 19.589,17.933 18.767,19.333C17.944,20.733 16.844,21.844 15.467,22.667H5.867ZM6.667,20H14.667C15.511,19.356 16.167,18.578 16.633,17.667C17.1,16.733 17.333,15.733 17.333,14.667C17.333,12.822 16.678,11.256 15.367,9.967C14.078,8.656 12.511,8 10.667,8C8.822,8 7.244,8.656 5.933,9.967C4.644,11.256 4,12.822 4,14.667C4,15.733 4.233,16.733 4.7,17.667C5.167,18.578 5.822,19.356 6.667,20ZM7.2,26.667C6.822,26.667 6.5,26.544 6.233,26.3C5.989,26.033 5.867,25.711 5.867,25.333C5.867,24.956 5.989,24.644 6.233,24.4C6.5,24.133 6.822,24 7.2,24H14.133C14.511,24 14.822,24.133 15.067,24.4C15.333,24.644 15.467,24.956 15.467,25.333C15.467,25.711 15.333,26.033 15.067,26.3C14.822,26.544 14.511,26.667 14.133,26.667H7.2ZM10.667,30.667C9.933,30.667 9.3,30.411 8.767,29.9C8.256,29.367 8,28.733 8,28H13.333C13.333,28.733 13.067,29.367 12.533,29.9C12.022,30.411 11.4,30.667 10.667,30.667ZM24.667,13.367C24.667,11.7 24.078,10.278 22.9,9.1C21.722,7.922 20.3,7.333 18.633,7.333C20.3,7.333 21.722,6.756 22.9,5.6C24.078,4.422 24.667,3 24.667,1.333C24.667,3 25.244,4.422 26.4,5.6C27.578,6.756 29,7.333 30.667,7.333C29,7.333 27.578,7.922 26.4,9.1C25.244,10.278 24.667,11.7 24.667,13.367Z"
-            android:fillColor="?androidprv:attr/materialColorPrimary"/>
+            android:fillColor="@androidprv:color/materialColorPrimary"/>
     </group>
 </vector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_restart_button_background_ripple.xml b/libs/WindowManager/Shell/res/drawable/letterbox_restart_button_background_ripple.xml
index 4207482..4e77720 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_restart_button_background_ripple.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_restart_button_background_ripple.xml
@@ -32,7 +32,7 @@
         </item>
         <item>
             <shape android:shape="rectangle">
-                <solid android:color="?androidprv:attr/materialColorPrimary"/>
+                <solid android:color="@androidprv:color/materialColorPrimary"/>
                 <corners android:radius="@dimen/letterbox_restart_dialog_button_radius"/>
                 <padding android:left="@dimen/letterbox_restart_dialog_horizontal_padding"
                          android:top="@dimen/letterbox_restart_dialog_vertical_padding"
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_restart_dialog_background.xml b/libs/WindowManager/Shell/res/drawable/letterbox_restart_dialog_background.xml
index 72cfeef..90b314a 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_restart_dialog_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_restart_dialog_background.xml
@@ -17,6 +17,6 @@
 <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="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+    <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh"/>
     <corners android:radius="@dimen/letterbox_restart_dialog_corner_radius"/>
 </shape>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_restart_dismiss_button_background_ripple.xml b/libs/WindowManager/Shell/res/drawable/letterbox_restart_dismiss_button_background_ripple.xml
index 816b350..d64e632 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_restart_dismiss_button_background_ripple.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_restart_dismiss_button_background_ripple.xml
@@ -32,9 +32,9 @@
         </item>
         <item>
             <shape android:shape="rectangle">
-                <stroke android:color="?androidprv:attr/materialColorOutlineVariant"
+                <stroke android:color="@androidprv:color/materialColorOutlineVariant"
                         android:width="1dp"/>
-                <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+                <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh"/>
                 <corners android:radius="@dimen/letterbox_restart_dialog_button_radius"/>
                 <padding android:left="@dimen/letterbox_restart_dialog_horizontal_padding"
                          android:top="@dimen/letterbox_restart_dialog_vertical_padding"
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_restart_header_ic_arrows.xml b/libs/WindowManager/Shell/res/drawable/letterbox_restart_header_ic_arrows.xml
index f13d26c..53b4a4b 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_restart_header_ic_arrows.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_restart_header_ic_arrows.xml
@@ -25,6 +25,6 @@
             android:pathData="M0,0h32v32h-32z"/>
         <path
             android:pathData="M8.533,25.333H10.667C11.044,25.333 11.356,25.467 11.6,25.733C11.867,25.978 12,26.289 12,26.667C12,27.044 11.867,27.367 11.6,27.633C11.356,27.878 11.044,28 10.667,28H5.333C4.956,28 4.633,27.878 4.367,27.633C4.122,27.367 4,27.044 4,26.667V21.333C4,20.956 4.122,20.644 4.367,20.4C4.633,20.133 4.956,20 5.333,20C5.711,20 6.022,20.133 6.267,20.4C6.533,20.644 6.667,20.956 6.667,21.333V23.467L9.867,20.267C10.111,20.022 10.422,19.9 10.8,19.9C11.178,19.9 11.489,20.022 11.733,20.267C11.978,20.511 12.1,20.822 12.1,21.2C12.1,21.578 11.978,21.889 11.733,22.133L8.533,25.333ZM23.467,25.333L20.267,22.133C20.022,21.889 19.9,21.578 19.9,21.2C19.9,20.822 20.022,20.511 20.267,20.267C20.511,20.022 20.822,19.9 21.2,19.9C21.578,19.9 21.889,20.022 22.133,20.267L25.333,23.467V21.333C25.333,20.956 25.456,20.644 25.7,20.4C25.967,20.133 26.289,20 26.667,20C27.044,20 27.356,20.133 27.6,20.4C27.867,20.644 28,20.956 28,21.333V26.667C28,27.044 27.867,27.367 27.6,27.633C27.356,27.878 27.044,28 26.667,28H21.333C20.956,28 20.633,27.878 20.367,27.633C20.122,27.367 20,27.044 20,26.667C20,26.289 20.122,25.978 20.367,25.733C20.633,25.467 20.956,25.333 21.333,25.333H23.467ZM6.667,8.533V10.667C6.667,11.044 6.533,11.367 6.267,11.633C6.022,11.878 5.711,12 5.333,12C4.956,12 4.633,11.878 4.367,11.633C4.122,11.367 4,11.044 4,10.667V5.333C4,4.956 4.122,4.644 4.367,4.4C4.633,4.133 4.956,4 5.333,4H10.667C11.044,4 11.356,4.133 11.6,4.4C11.867,4.644 12,4.956 12,5.333C12,5.711 11.867,6.033 11.6,6.3C11.356,6.544 11.044,6.667 10.667,6.667H8.533L11.733,9.867C11.978,10.111 12.1,10.422 12.1,10.8C12.1,11.178 11.978,11.489 11.733,11.733C11.489,11.978 11.178,12.1 10.8,12.1C10.422,12.1 10.111,11.978 9.867,11.733L6.667,8.533ZM25.333,8.533L22.133,11.733C21.889,11.978 21.578,12.1 21.2,12.1C20.822,12.1 20.511,11.978 20.267,11.733C20.022,11.489 19.9,11.178 19.9,10.8C19.9,10.422 20.022,10.111 20.267,9.867L23.467,6.667H21.333C20.956,6.667 20.633,6.544 20.367,6.3C20.122,6.033 20,5.711 20,5.333C20,4.956 20.122,4.644 20.367,4.4C20.633,4.133 20.956,4 21.333,4H26.667C27.044,4 27.356,4.133 27.6,4.4C27.867,4.644 28,4.956 28,5.333V10.667C28,11.044 27.867,11.367 27.6,11.633C27.356,11.878 27.044,12 26.667,12C26.289,12 25.967,11.878 25.7,11.633C25.456,11.367 25.333,11.044 25.333,10.667V8.533Z"
-            android:fillColor="?androidprv:attr/materialColorPrimary"/>
+            android:fillColor="@androidprv:color/materialColorPrimary"/>
     </group>
 </vector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_background.xml b/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_background.xml
index 4eb2271..d1a510a 100644
--- a/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_background.xml
@@ -17,6 +17,6 @@
 <shape android:shape="rectangle"
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <solid android:color="?androidprv:attr/materialColorSurfaceContainer"/>
+    <solid android:color="@androidprv:color/materialColorSurfaceContainer"/>
     <corners android:radius="28dp"/>
 </shape>
diff --git a/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_confirm_button_background.xml b/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_confirm_button_background.xml
index 2b2e9df..20e2e7e 100644
--- a/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_confirm_button_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_confirm_button_background.xml
@@ -17,6 +17,6 @@
 <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="?androidprv:attr/materialColorPrimary"/>
+    <solid android:color="@androidprv:color/materialColorPrimary"/>
     <corners android:radius="50dp"/>
 </shape>
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml
index 4c7d1c7..7347fbad 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml
@@ -29,7 +29,7 @@
     <ImageView
         android:layout_width="@dimen/bubble_popup_icon_size"
         android:layout_height="@dimen/bubble_popup_icon_size"
-        android:tint="?androidprv:attr/materialColorOutline"
+        android:tint="@androidprv:color/materialColorOutline"
         android:contentDescription="@null"
         android:src="@drawable/pip_ic_settings"/>
 
@@ -41,7 +41,7 @@
         android:maxLines="1"
         android:ellipsize="end"
         android:textAppearance="@android:style/TextAppearance.DeviceDefault.Headline"
-        android:textColor="?androidprv:attr/materialColorOnSurface"
+        android:textColor="@androidprv:color/materialColorOnSurface"
         android:text="@string/bubble_bar_education_manage_title"/>
 
     <TextView
@@ -51,7 +51,7 @@
         android:paddingBottom="@dimen/bubble_popup_padding_bottom"
         android:maxWidth="@dimen/bubble_popup_content_max_width"
         android:textAppearance="@android:style/TextAppearance.DeviceDefault"
-        android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+        android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
         android:textAlignment="center"
         android:text="@string/bubble_bar_education_manage_text"/>
 
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_menu_item.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_menu_item.xml
index e3217811..5750ed7 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_bar_menu_item.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_menu_item.xml
@@ -36,7 +36,7 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginStart="16dp"
-        android:textColor="?androidprv:attr/materialColorOnSurface"
+        android:textColor="@androidprv:color/materialColorOnSurface"
         android:textAppearance="@*android:style/TextAppearance.DeviceDefault" />
 
 </com.android.wm.shell.bubbles.bar.BubbleBarMenuItemView>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml
index 7aca921..cef4f5f 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml
@@ -50,8 +50,9 @@
             android:layout_height="wrap_content"
             android:layout_marginStart="8dp"
             android:layout_weight="1"
-            android:textColor="?androidprv:attr/materialColorOnSurface"
-            android:textAppearance="@*android:style/TextAppearance.DeviceDefault" />
+            android:textColor="@androidprv:color/materialColorOnSurface"
+            android:textAppearance="@*android:style/TextAppearance.DeviceDefault"
+            android:textDirection="locale" />
 
         <ImageView
             android:id="@+id/bubble_bar_manage_menu_dismiss_icon"
@@ -60,7 +61,7 @@
             android:layout_marginStart="8dp"
             android:contentDescription="@null"
             android:src="@drawable/ic_expand_less"
-            app:tint="?androidprv:attr/materialColorOnSurface" />
+            app:tint="@androidprv:color/materialColorOnSurface" />
 
     </LinearLayout>
 
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_stack_education.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_stack_education.xml
index 345c399..f0e18711 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_bar_stack_education.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_stack_education.xml
@@ -29,7 +29,7 @@
     <ImageView
         android:layout_width="@dimen/bubble_popup_icon_size"
         android:layout_height="@dimen/bubble_popup_icon_size"
-        android:tint="?androidprv:attr/materialColorOutline"
+        android:tint="@androidprv:color/materialColorOutline"
         android:contentDescription="@null"
         android:src="@drawable/ic_floating_landscape"/>
 
@@ -41,7 +41,7 @@
         android:maxLines="1"
         android:ellipsize="end"
         android:textAppearance="@android:style/TextAppearance.DeviceDefault.Headline"
-        android:textColor="?androidprv:attr/materialColorOnSurface"
+        android:textColor="@androidprv:color/materialColorOnSurface"
         android:text="@string/bubble_bar_education_stack_title"/>
 
     <TextView
@@ -51,7 +51,7 @@
         android:paddingBottom="@dimen/bubble_popup_padding_bottom"
         android:maxWidth="@dimen/bubble_popup_content_max_width"
         android:textAppearance="@android:style/TextAppearance.DeviceDefault"
-        android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+        android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
         android:textAlignment="center"
         android:text="@string/bubble_bar_education_stack_text"/>
 
diff --git a/libs/WindowManager/Shell/res/layout/bubble_flyout.xml b/libs/WindowManager/Shell/res/layout/bubble_flyout.xml
index 65a07a7..deabd56 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_flyout.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_flyout.xml
@@ -49,7 +49,7 @@
                 android:fontFamily="@*android:string/config_bodyFontFamilyMedium"
                 android:maxLines="1"
                 android:ellipsize="end"
-                android:textColor="?androidprv:attr/materialColorOnSurface"
+                android:textColor="@androidprv:color/materialColorOnSurface"
                 android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"/>
 
             <TextView
@@ -59,7 +59,7 @@
                 android:fontFamily="@*android:string/config_bodyFontFamily"
                 android:maxLines="2"
                 android:ellipsize="end"
-                android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+                android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
                 android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"/>
 
         </LinearLayout>
diff --git a/libs/WindowManager/Shell/res/layout/bubble_manage_button.xml b/libs/WindowManager/Shell/res/layout/bubble_manage_button.xml
index f88d63d..0c446df 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_manage_button.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_manage_button.xml
@@ -28,6 +28,6 @@
     android:focusable="true"
     android:text="@string/manage_bubbles_text"
     android:textSize="@*android:dimen/text_size_body_2_material"
-    android:textColor="?androidprv:attr/materialColorOnSurface"
+    android:textColor="@androidprv:color/materialColorOnSurface"
     android:background="@drawable/bubble_manage_btn_bg"
     />
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
index d8ae9c8..4daaf9c 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
@@ -43,7 +43,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="16dp"
-            android:textColor="?androidprv:attr/materialColorOnSurface"
+            android:textColor="@androidprv:color/materialColorOnSurface"
             android:textAppearance="@*android:style/TextAppearance.DeviceDefault"
             android:text="@string/bubble_dismiss_text" />
 
@@ -70,7 +70,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="16dp"
-            android:textColor="?androidprv:attr/materialColorOnSurface"
+            android:textColor="@androidprv:color/materialColorOnSurface"
             android:textAppearance="@*android:style/TextAppearance.DeviceDefault"
             android:text="@string/bubbles_dont_bubble_conversation" />
 
@@ -98,7 +98,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="16dp"
-            android:textColor="?androidprv:attr/materialColorOnSurface"
+            android:textColor="@androidprv:color/materialColorOnSurface"
             android:textAppearance="@*android:style/TextAppearance.DeviceDefault" />
 
     </LinearLayout>
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 bfd9c81..b69563b 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:layout_height="wrap_content"
             tools:text="Gmail"
             android:importantForAccessibility="no"
-            android:textColor="?androidprv:attr/materialColorOnSurface"
+            android:textColor="@androidprv:color/materialColorOnSurface"
             android:textSize="14sp"
             android:textFontWeight="500"
             android:lineHeight="20dp"
@@ -69,7 +69,7 @@
             android:contentDescription="@string/collapse_menu_text"
             android:src="@drawable/ic_baseline_expand_more_24"
             android:rotation="180"
-            android:tint="?androidprv:attr/materialColorOnSurface"
+            android:tint="@androidprv:color/materialColorOnSurface"
             android:background="?android:selectableItemBackgroundBorderless"/>
     </LinearLayout>
 
@@ -89,7 +89,7 @@
             android:layout_marginEnd="4dp"
             android:contentDescription="@string/fullscreen_text"
             android:src="@drawable/desktop_mode_ic_handle_menu_fullscreen"
-            android:tint="?androidprv:attr/materialColorOnSurface"
+            android:tint="@androidprv:color/materialColorOnSurface"
             android:layout_weight="1"
             style="@style/DesktopModeHandleMenuWindowingButton"/>
 
@@ -99,7 +99,7 @@
             android:layout_marginEnd="4dp"
             android:contentDescription="@string/split_screen_text"
             android:src="@drawable/desktop_mode_ic_handle_menu_splitscreen"
-            android:tint="?androidprv:attr/materialColorOnSurface"
+            android:tint="@androidprv:color/materialColorOnSurface"
             android:layout_weight="1"
             style="@style/DesktopModeHandleMenuWindowingButton"/>
 
@@ -109,7 +109,7 @@
             android:layout_marginEnd="4dp"
             android:contentDescription="@string/float_button_text"
             android:src="@drawable/desktop_mode_ic_handle_menu_floating"
-            android:tint="?androidprv:attr/materialColorOnSurface"
+            android:tint="@androidprv:color/materialColorOnSurface"
             android:layout_weight="1"
             style="@style/DesktopModeHandleMenuWindowingButton"/>
 
@@ -118,7 +118,7 @@
             android:layout_marginStart="4dp"
             android:contentDescription="@string/desktop_text"
             android:src="@drawable/desktop_mode_ic_handle_menu_desktop"
-            android:tint="?androidprv:attr/materialColorOnSurface"
+            android:tint="@androidprv:color/materialColorOnSurface"
             android:layout_weight="1"
             style="@style/DesktopModeHandleMenuWindowingButton"/>
 
@@ -139,7 +139,7 @@
             android:contentDescription="@string/screenshot_text"
             android:text="@string/screenshot_text"
             android:drawableStart="@drawable/desktop_mode_ic_handle_menu_screenshot"
-            android:drawableTint="?androidprv:attr/materialColorOnSurface"
+            android:drawableTint="@androidprv:color/materialColorOnSurface"
             style="@style/DesktopModeHandleMenuActionButton"/>
 
         <Button
@@ -147,7 +147,7 @@
             android:contentDescription="@string/new_window_text"
             android:text="@string/new_window_text"
             android:drawableStart="@drawable/desktop_mode_ic_handle_menu_new_window"
-            android:drawableTint="?androidprv:attr/materialColorOnSurface"
+            android:drawableTint="@androidprv:color/materialColorOnSurface"
             style="@style/DesktopModeHandleMenuActionButton" />
 
         <Button
@@ -155,7 +155,7 @@
             android:contentDescription="@string/manage_windows_text"
             android:text="@string/manage_windows_text"
             android:drawableStart="@drawable/desktop_mode_ic_handle_menu_manage_windows"
-            android:drawableTint="?androidprv:attr/materialColorOnSurface"
+            android:drawableTint="@androidprv:color/materialColorOnSurface"
             style="@style/DesktopModeHandleMenuActionButton" />
 
         <Button
@@ -163,7 +163,7 @@
             android:contentDescription="@string/change_aspect_ratio_text"
             android:text="@string/change_aspect_ratio_text"
             android:drawableStart="@drawable/desktop_mode_ic_handle_menu_change_aspect_ratio"
-            android:drawableTint="?androidprv:attr/materialColorOnSurface"
+            android:drawableTint="@androidprv:color/materialColorOnSurface"
             style="@style/DesktopModeHandleMenuActionButton" />
     </LinearLayout>
 
@@ -183,7 +183,7 @@
             android:contentDescription="@string/open_in_browser_text"
             android:text="@string/open_in_browser_text"
             android:drawableStart="@drawable/desktop_mode_ic_handle_menu_open_in_browser"
-            android:drawableTint="?androidprv:attr/materialColorOnSurface"
+            android:drawableTint="@androidprv:color/materialColorOnSurface"
             style="@style/DesktopModeHandleMenuActionButton"/>
 
         <ImageButton
@@ -195,7 +195,7 @@
             android:layout_marginStart="10dp"
             android:contentDescription="@string/open_by_default_settings_text"
             android:src="@drawable/desktop_mode_ic_handle_menu_open_by_default_settings"
-            android:tint="?androidprv:attr/materialColorOnSurface"/>
+            android:tint="@androidprv:color/materialColorOnSurface"/>
     </LinearLayout>
 </LinearLayout>
 
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 375968a..8d7e5fd 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
@@ -58,7 +58,7 @@
                 android:fontFamily="google-sans-text"
                 android:importantForAccessibility="no"
                 android:text="@string/desktop_mode_maximize_menu_immersive_button_text"
-                android:textColor="?androidprv:attr/materialColorOnSurface"
+                android:textColor="@androidprv:color/materialColorOnSurface"
                 android:alpha="0"/>
         </LinearLayout>
 
@@ -89,7 +89,7 @@
                 android:fontFamily="google-sans-text"
                 android:importantForAccessibility="no"
                 android:text="@string/desktop_mode_maximize_menu_maximize_text"
-                android:textColor="?androidprv:attr/materialColorOnSurface"
+                android:textColor="@androidprv:color/materialColorOnSurface"
                 android:alpha="0"/>
         </LinearLayout>
 
@@ -140,7 +140,7 @@
                 android:importantForAccessibility="no"
                 android:fontFamily="google-sans-text"
                 android:text="@string/desktop_mode_maximize_menu_snap_text"
-                android:textColor="?androidprv:attr/materialColorOnSurface"
+                android:textColor="@androidprv:color/materialColorOnSurface"
                 android:alpha="0"/>
         </LinearLayout>
     </LinearLayout>
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml
index bda087b..0a44cd4 100644
--- a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml
@@ -37,7 +37,7 @@
         android:layout_height="wrap_content"
         android:lineSpacingExtra="4sp"
         android:textAlignment="center"
-        android:textColor="?androidprv:attr/materialColorOnSurface"
+        android:textColor="@androidprv:color/materialColorOnSurface"
         android:textSize="14sp"/>
 
 </LinearLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
index 488123a..cd36983 100644
--- a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
@@ -64,7 +64,7 @@
                     android:lineSpacingExtra="4sp"
                     android:text="@string/letterbox_education_dialog_title"
                     android:textAlignment="center"
-                    android:textColor="?androidprv:attr/materialColorOnSurface"
+                    android:textColor="@androidprv:color/materialColorOnSurface"
                     android:fontFamily="@*android:string/config_headlineFontFamily"
                     android:textSize="24sp"/>
 
@@ -104,7 +104,7 @@
                     android:background=
                         "@drawable/letterbox_education_dismiss_button_background_ripple"
                     android:text="@string/letterbox_education_got_it"
-                    android:textColor="?androidprv:attr/materialColorOnPrimary"
+                    android:textColor="@androidprv:color/materialColorOnPrimary"
                     android:textAlignment="center"
                     android:contentDescription="@string/letterbox_education_got_it"/>
 
diff --git a/libs/WindowManager/Shell/res/layout/open_by_default_settings_dialog.xml b/libs/WindowManager/Shell/res/layout/open_by_default_settings_dialog.xml
index b5bceda..f6256e6 100644
--- a/libs/WindowManager/Shell/res/layout/open_by_default_settings_dialog.xml
+++ b/libs/WindowManager/Shell/res/layout/open_by_default_settings_dialog.xml
@@ -64,7 +64,7 @@
                     android:lineHeight="32dp"
                     android:textFontWeight="400"
                     android:textSize="24sp"
-                    android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+                    android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
                     tools:text="Gmail" />
 
                 <TextView
@@ -75,7 +75,7 @@
                     android:lineHeight="16dp"
                     android:layout_gravity="center_horizontal"
                     android:layout_marginBottom="16dp"
-                    android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+                    android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
                     android:text="@string/open_by_default_dialog_subheader_text"/>
 
                 <RadioGroup
@@ -121,7 +121,7 @@
                     android:layout_marginBottom="24dp"
                     android:textSize="14sp"
                     android:textFontWeight="500"
-                    android:textColor="?androidprv:attr/materialColorOnPrimary"
+                    android:textColor="@androidprv:color/materialColorOnPrimary"
                     android:background="@drawable/open_by_default_settings_dialog_confirm_button_background"/>
             </LinearLayout>
         </ScrollView>
diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml
index b7aa158..d754243 100644
--- a/libs/WindowManager/Shell/res/values/colors.xml
+++ b/libs/WindowManager/Shell/res/values/colors.xml
@@ -43,7 +43,7 @@
     <color name="compat_controls_text">@android:color/system_neutral1_50</color>
 
     <!-- Letterbox Education -->
-    <color name="letterbox_education_text_secondary">?androidprv:attr/materialColorSecondary</color>
+    <color name="letterbox_education_text_secondary">@androidprv:color/materialColorSecondary</color>
 
     <!-- Letterbox Dialog -->
     <color name="letterbox_dialog_background">@android:color/system_neutral1_900</color>
diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml
index 597a921..8a4a702 100644
--- a/libs/WindowManager/Shell/res/values/styles.xml
+++ b/libs/WindowManager/Shell/res/values/styles.xml
@@ -48,7 +48,7 @@
         <item name="android:paddingEnd">0dp</item>
         <item name="android:textSize">14sp</item>
         <item name="android:textFontWeight">500</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
         <item name="android:drawablePadding">16dp</item>
         <item name="android:background">?android:selectableItemBackground</item>
     </style>
@@ -92,7 +92,7 @@
 
     <style name="RestartDialogTitleText">
         <item name="android:textSize">24sp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
         <item name="android:lineSpacingExtra">8sp</item>
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
     </style>
@@ -104,23 +104,23 @@
 
     <style name="RestartDialogBodyText" parent="RestartDialogBodyStyle">
         <item name="android:letterSpacing">0.02</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
         <item name="android:lineSpacingExtra">6sp</item>
     </style>
 
     <style name="RestartDialogCheckboxText" parent="RestartDialogBodyStyle">
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
         <item name="android:lineSpacingExtra">6sp</item>
     </style>
 
     <style name="RestartDialogDismissButton" parent="RestartDialogBodyStyle">
         <item name="android:lineSpacingExtra">2sp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorPrimary</item>
+        <item name="android:textColor">@androidprv:color/materialColorPrimary</item>
     </style>
 
     <style name="RestartDialogConfirmButton" parent="RestartDialogBodyStyle">
         <item name="android:lineSpacingExtra">2sp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnPrimary</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnPrimary</item>
     </style>
 
     <style name="ReachabilityEduHandLayout" parent="Theme.AppCompat.Light">
diff --git a/libs/WindowManager/Shell/shared/Android.bp b/libs/WindowManager/Shell/shared/Android.bp
index 5113d98..c3ee0f7 100644
--- a/libs/WindowManager/Shell/shared/Android.bp
+++ b/libs/WindowManager/Shell/shared/Android.bp
@@ -71,6 +71,7 @@
     srcs: [
         "**/desktopmode/*.java",
         "**/desktopmode/*.kt",
+        ":wm_shell-shared-utils",
     ],
     static_libs: [
         "com.android.window.flags.window-aconfig-java",
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
index a5205ee..755f472 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
@@ -16,9 +16,15 @@
 
 package com.android.wm.shell.shared.desktopmode;
 
+import static android.hardware.display.DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED;
+
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
+import android.hardware.display.DisplayManager;
 import android.os.SystemProperties;
+import android.view.Display;
+import android.view.WindowManager;
 import android.window.DesktopModeFlags;
 
 import com.android.internal.R;
@@ -26,6 +32,7 @@
 import com.android.window.flags.Flags;
 
 import java.io.PrintWriter;
+import java.util.Arrays;
 
 /**
  * Constants for desktop mode feature
@@ -35,6 +42,9 @@
 
     private static final String TAG = "DesktopModeStatus";
 
+    @Nullable
+    private static Boolean sIsLargeScreenDevice = null;
+
     /**
      * Flag to indicate whether task resizing is veiled.
      */
@@ -91,6 +101,9 @@
     /** The maximum override density allowed for tasks inside the desktop. */
     private static final int DESKTOP_DENSITY_MAX = 1000;
 
+    /** The number of [WindowDecorViewHost] instances to warm up on system start. */
+    private static final int WINDOW_DECOR_PRE_WARM_SIZE = 2;
+
     /**
      * Sysprop declaring whether to enters desktop mode by default when the windowing mode of the
      * display's root TaskDisplayArea is set to WINDOWING_MODE_FREEFORM.
@@ -122,6 +135,14 @@
     private static final String MAX_TASK_LIMIT_SYS_PROP = "persist.wm.debug.desktop_max_task_limit";
 
     /**
+     * Sysprop declaring the number of [WindowDecorViewHost] instances to warm up on system start.
+     *
+     * <p>If it is not defined, then [WINDOW_DECOR_PRE_WARM_SIZE] is used.
+     */
+    private static final String WINDOW_DECOR_PRE_WARM_SIZE_SYS_PROP =
+            "persist.wm.debug.desktop_window_decor_pre_warm_size";
+
+    /**
      * Return {@code true} if veiled resizing is active. If false, fluid resizing is used.
      */
     public static boolean isVeiledResizeEnabled() {
@@ -176,6 +197,12 @@
         return 0;
     }
 
+    /** The number of [WindowDecorViewHost] instances to warm up on system start. */
+    public static int getWindowDecorPreWarmSize() {
+        return SystemProperties.getInt(WINDOW_DECOR_PRE_WARM_SIZE_SYS_PROP,
+                WINDOW_DECOR_PRE_WARM_SIZE);
+    }
+
     /**
      * Return {@code true} if the current device supports desktop mode.
      */
@@ -210,13 +237,12 @@
      * necessarily enabling desktop mode
      */
     public static boolean overridesShowAppHandle(@NonNull Context context) {
-        return Flags.showAppHandleLargeScreens()
-                && context.getResources().getBoolean(R.bool.config_enableAppHandle);
+        return Flags.showAppHandleLargeScreens() && deviceHasLargeScreen(context);
     }
 
     /**
      * @return {@code true} if the app handle should be shown because desktop mode is enabled or
-     * the device is overriding {@code R.bool.config_enableAppHandle}
+     * the device has a large screen
      */
     public static boolean canEnterDesktopModeOrShowAppHandle(@NonNull Context context) {
         return canEnterDesktopMode(context) || overridesShowAppHandle(context);
@@ -259,6 +285,21 @@
     }
 
     /**
+     * @return {@code true} if this device has an internal large screen
+     */
+    private static boolean deviceHasLargeScreen(@NonNull Context context) {
+        if (sIsLargeScreenDevice == null) {
+            sIsLargeScreenDevice = Arrays.stream(
+                context.getSystemService(DisplayManager.class)
+                        .getDisplays(DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED))
+                .filter(display -> display.getType() == Display.TYPE_INTERNAL)
+                .anyMatch(display -> display.getMinSizeDimensionDp()
+                        >= WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP);
+        }
+        return sIsLargeScreenDevice;
+    }
+
+    /**
      * Return {@code true} if a display should enter desktop mode by default when the windowing mode
      * of the display's root [TaskDisplayArea] is set to WINDOWING_MODE_FREEFORM.
      */
@@ -298,6 +339,6 @@
         pw.println(maxTaskLimitHandle == null ? "null" : maxTaskLimitHandle.getInt(/* def= */ -1));
 
         pw.print(innerPrefix); pw.print("showAppHandle config override=");
-        pw.print(context.getResources().getBoolean(R.bool.config_enableAppHandle));
+        pw.print(overridesShowAppHandle(context));
     }
 }
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/split/SplitScreenConstants.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/split/SplitScreenConstants.java
index f9f43bc..b48296f5 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/split/SplitScreenConstants.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/split/SplitScreenConstants.java
@@ -58,6 +58,11 @@
      */
     public static final int SPLIT_POSITION_BOTTOM_OR_RIGHT = 1;
 
+    /**
+     * Deprecated and will be replaced fully by @SplitIndex. With support for 3+ apps in split,
+     * existing references to top/left and bottom/right will be replaced by INDEX_0 and INDEX_1
+     * respectively. For now they can be used interchangeably, the underlying ints are the same.
+     */
     @IntDef(prefix = {"SPLIT_POSITION_"}, value = {
             SPLIT_POSITION_UNDEFINED,
             SPLIT_POSITION_TOP_OR_LEFT,
@@ -85,6 +90,21 @@
     public @interface SplitIndex {
     }
 
+    /**
+     * Return the @SplitIndex constant for a given integer index. @SplitIndex is the replacement
+     * for @SplitPosition, and will be used interchangeably with @SplitPosition to support 3+ apps
+     * in split.
+     */
+    public static int getIndex(int i) {
+        return switch (i) {
+            case 0 -> SPLIT_INDEX_0;
+            case 1 -> SPLIT_INDEX_1;
+            case 2 -> SPLIT_INDEX_2;
+            case 3 -> SPLIT_INDEX_3;
+            default -> SPLIT_INDEX_UNDEFINED;
+        };
+    }
+
     /** Signifies that user is currently not in split screen. */
     public static final int NOT_IN_SPLIT = -1;
 
@@ -159,7 +179,8 @@
      * {@link PersistentSnapPosition} + {@link #NOT_IN_SPLIT}.
      */
     @IntDef(value = {
-            NOT_IN_SPLIT,
+            NOT_IN_SPLIT, // user is not in split screen
+            SNAP_TO_NONE, // in "free snap mode," where apps are fully resizable
             SNAP_TO_2_33_66,
             SNAP_TO_2_50_50,
             SNAP_TO_2_66_33,
@@ -171,6 +192,23 @@
     })
     public @interface SplitScreenState {}
 
+    /** Converts a {@link SplitScreenState} to a human-readable string. */
+    public static String stateToString(@SplitScreenState int state) {
+        return switch (state) {
+            case NOT_IN_SPLIT -> "NOT_IN_SPLIT";
+            case SNAP_TO_NONE -> "SNAP_TO_NONE";
+            case SNAP_TO_2_33_66 -> "SNAP_TO_2_33_66";
+            case SNAP_TO_2_50_50 -> "SNAP_TO_2_50_50";
+            case SNAP_TO_2_66_33 -> "SNAP_TO_2_66_33";
+            case SNAP_TO_2_90_10 -> "SNAP_TO_2_90_10";
+            case SNAP_TO_2_10_90 -> "SNAP_TO_2_10_90";
+            case SNAP_TO_3_33_33_33 -> "SNAP_TO_3_33_33_33";
+            case SNAP_TO_3_45_45_10 -> "SNAP_TO_3_45_45_10";
+            case SNAP_TO_3_10_45_45 -> "SNAP_TO_3_10_45_45";
+            default -> "UNKNOWN";
+        };
+    }
+
     /**
      * Checks if the snapPosition in question is a {@link PersistentSnapPosition}.
      */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/AppToWebUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/AppToWebUtils.kt
index 7243ea3..68c42d6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/AppToWebUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/AppToWebUtils.kt
@@ -18,6 +18,8 @@
 
 package com.android.wm.shell.apptoweb
 
+import android.app.assist.AssistContent
+import android.app.assist.AssistContent.EXTRA_SESSION_TRANSFER_WEB_URI
 import android.content.Context
 import android.content.Intent
 import android.content.Intent.ACTION_VIEW
@@ -102,3 +104,10 @@
         return null
     }
 }
+
+/**
+ * Returns the web uri from the given [AssistContent].
+ */
+fun AssistContent.getSessionWebUri(): Uri? {
+    return extras.getParcelable(EXTRA_SESSION_TRANSFER_WEB_URI) ?: webUri
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OpenByDefaultDialog.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OpenByDefaultDialog.kt
index a727b54..4cc81a9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OpenByDefaultDialog.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OpenByDefaultDialog.kt
@@ -17,7 +17,6 @@
 package com.android.wm.shell.apptoweb
 
 import android.app.ActivityManager.RunningTaskInfo
-import android.app.TaskInfo
 import android.content.Context
 import android.content.pm.verify.domain.DomainVerificationManager
 import android.graphics.Bitmap
@@ -36,8 +35,17 @@
 import android.window.TaskConstants
 import com.android.wm.shell.R
 import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.shared.annotations.ShellBackgroundThread
+import com.android.wm.shell.shared.annotations.ShellMainThread
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewHostViewContainer
+import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader
 import java.util.function.Supplier
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.MainCoroutineDispatcher
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 
 
 /**
@@ -45,13 +53,14 @@
  */
 internal class OpenByDefaultDialog(
     private val context: Context,
-    private val taskInfo: TaskInfo,
+    private val taskInfo: RunningTaskInfo,
     private val taskSurface: SurfaceControl,
     private val displayController: DisplayController,
+    private val taskResourceLoader: WindowDecorTaskResourceLoader,
     private val surfaceControlTransactionSupplier: Supplier<SurfaceControl.Transaction>,
+    @ShellMainThread private val mainDispatcher: MainCoroutineDispatcher,
+    @ShellBackgroundThread private val bgScope: CoroutineScope,
     private val listener: DialogLifecycleListener,
-    appIconBitmap: Bitmap?,
-    appName: CharSequence?
 ) {
     private lateinit var dialog: OpenByDefaultDialogView
     private lateinit var viewHost: SurfaceControlViewHost
@@ -67,11 +76,20 @@
         context.getSystemService(DomainVerificationManager::class.java)!!
     private val packageName = taskInfo.baseActivity?.packageName!!
 
+    private var loadAppInfoJob: Job? = null
 
     init {
         createDialog()
         initializeRadioButtons()
-        bindAppInfo(appIconBitmap, appName)
+        loadAppInfoJob = bgScope.launch {
+            if (!isActive) return@launch
+            val name = taskResourceLoader.getName(taskInfo)
+            val icon = taskResourceLoader.getHeaderIcon(taskInfo)
+            withContext(mainDispatcher.immediate) {
+                if (!isActive) return@withContext
+                bindAppInfo(icon, name)
+            }
+        }
     }
 
     /** Creates an open by default settings dialog. */
@@ -147,14 +165,15 @@
     }
 
     private fun closeMenu() {
+        loadAppInfoJob?.cancel()
         dialogContainer?.releaseView()
         dialogContainer = null
         listener.onDialogDismissed()
     }
 
      private fun bindAppInfo(
-        appIconBitmap: Bitmap?,
-        appName: CharSequence?
+        appIconBitmap: Bitmap,
+        appName: CharSequence
     ) {
         appIconView.setImageBitmap(appIconBitmap)
         appNameView.text = appName
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 673d8b3..56efdb8 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
@@ -214,6 +214,10 @@
                         }
                         ProtoLog.i(WM_SHELL_BACK_PREVIEW, "Navigation window gone.");
                         setTriggerBack(false);
+                        // Trigger close transition if necessary.
+                        if (Flags.migratePredictiveBackTransition()) {
+                            mBackTransitionHandler.onAnimationFinished();
+                        }
                         resetTouchTracker();
                         // Don't wait for animation start
                         mShellExecutor.removeCallbacks(mAnimationTimeoutRunnable);
@@ -1310,7 +1314,7 @@
                 }
             }
 
-            if (handlePrepareTransition(info, st, ft, finishCallback)) {
+            if (handlePrepareTransition(transition, info, st, ft, finishCallback)) {
                 if (checkTakeoverFlags()) {
                     mTakeoverHandler = mTransitions.getHandlerForTakeover(transition, info);
                 }
@@ -1626,7 +1630,7 @@
          * happen when core make an activity become visible.
          */
         @VisibleForTesting
-        boolean handlePrepareTransition(
+        boolean handlePrepareTransition(@NonNull IBinder transition,
                 @NonNull TransitionInfo info,
                 @NonNull SurfaceControl.Transaction st,
                 @NonNull SurfaceControl.Transaction ft,
@@ -1674,6 +1678,8 @@
                 }
             }
             st.apply();
+            // In case other transition handler took the handleRequest before this class.
+            mPrepareOpenTransition = transition;
             mFinishOpenTransaction = ft;
             mFinishOpenTransitionCallback = finishCallback;
             mOpenTransitionInfo = info;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index 5295526..47032fd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -38,7 +38,6 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
-import android.graphics.Color;
 import android.graphics.CornerPathEffect;
 import android.graphics.Outline;
 import android.graphics.Paint;
@@ -543,15 +542,15 @@
 
     void applyThemeAttrs() {
         final TypedArray ta = mContext.obtainStyledAttributes(new int[]{
-                android.R.attr.dialogCornerRadius,
-                com.android.internal.R.attr.materialColorSurfaceBright,
-                com.android.internal.R.attr.materialColorSurfaceContainerHigh});
+                android.R.attr.dialogCornerRadius});
         boolean supportsRoundedCorners = ScreenDecorationsUtils.supportsRoundedCornersOnWindows(
                 mContext.getResources());
         mCornerRadius = supportsRoundedCorners ? ta.getDimensionPixelSize(0, 0) : 0;
-        mBackgroundColorFloating = ta.getColor(1, Color.WHITE);
+        mBackgroundColorFloating = mContext.getColor(
+                com.android.internal.R.color.materialColorSurfaceBright);
         mExpandedViewContainer.setBackgroundColor(mBackgroundColorFloating);
-        final int manageMenuBg = ta.getColor(2, Color.WHITE);
+        final int manageMenuBg = mContext.getColor(
+                com.android.internal.R.color.materialColorSurfaceContainerHigh);
         ta.recycle();
         if (mManageButton != null) {
             mManageButton.getBackground().setColorFilter(manageMenuBg, PorterDuff.Mode.SRC_IN);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
index 1711dca..da6948d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
@@ -28,7 +28,6 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
-import android.graphics.Color;
 import android.graphics.Matrix;
 import android.graphics.Outline;
 import android.graphics.Paint;
@@ -209,7 +208,7 @@
                         mPointerSize, mPointerSize, false /* isPointingLeft */));
         mRightTriangleShape.setBounds(0, 0, mPointerSize, mPointerSize);
 
-        applyConfigurationColors(getResources().getConfiguration());
+        applyConfigurationColors();
     }
 
     @Override
@@ -440,29 +439,23 @@
         boolean flagsChanged = nightModeFlags != mNightModeFlags;
         if (flagsChanged) {
             mNightModeFlags = nightModeFlags;
-            applyConfigurationColors(configuration);
+            applyConfigurationColors();
         }
         return flagsChanged;
     }
 
-    private void applyConfigurationColors(Configuration configuration) {
-        int nightModeFlags = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK;
-        boolean isNightModeOn = nightModeFlags == Configuration.UI_MODE_NIGHT_YES;
-        try (TypedArray ta = mContext.obtainStyledAttributes(
-                new int[]{
-                        com.android.internal.R.attr.materialColorSurfaceContainer,
-                        com.android.internal.R.attr.materialColorOnSurface,
-                        com.android.internal.R.attr.materialColorOnSurfaceVariant})) {
-            mFloatingBackgroundColor = ta.getColor(0,
-                    isNightModeOn ? Color.BLACK : Color.WHITE);
-            mSenderText.setTextColor(ta.getColor(1,
-                    isNightModeOn ? Color.WHITE : Color.BLACK));
-            mMessageText.setTextColor(ta.getColor(2,
-                    isNightModeOn ? Color.WHITE : Color.BLACK));
-            mBgPaint.setColor(mFloatingBackgroundColor);
-            mLeftTriangleShape.getPaint().setColor(mFloatingBackgroundColor);
-            mRightTriangleShape.getPaint().setColor(mFloatingBackgroundColor);
-        }
+    private void applyConfigurationColors() {
+        mFloatingBackgroundColor = mContext.getColor(
+                com.android.internal.R.color.materialColorSurfaceContainer);
+        mSenderText.setTextColor(
+                mContext.getColor(com.android.internal.R.color.materialColorOnSurface));
+        mMessageText.setTextColor(
+                mContext.getColor(com.android.internal.R.color.materialColorOnSurfaceVariant));
+
+        mBgPaint.setColor(mFloatingBackgroundColor);
+        mLeftTriangleShape.getPaint().setColor(mFloatingBackgroundColor);
+        mRightTriangleShape.getPaint().setColor(mFloatingBackgroundColor);
+
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
index c74412b..862906a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
@@ -19,7 +19,6 @@
 import android.app.ActivityTaskManager.INVALID_TASK_ID
 import android.content.Context
 import android.graphics.Bitmap
-import android.graphics.Color
 import android.graphics.Matrix
 import android.graphics.Path
 import android.graphics.drawable.AdaptiveIconDrawable
@@ -117,18 +116,8 @@
         val res = context.resources
 
         // Set overflow button accent color, dot color
-
-        val typedArray =
-            context.obtainStyledAttributes(
-                intArrayOf(
-                    com.android.internal.R.attr.materialColorPrimaryFixed,
-                    com.android.internal.R.attr.materialColorOnPrimaryFixed
-                )
-            )
-
-        val colorAccent = typedArray.getColor(0, Color.WHITE)
-        val shapeColor = typedArray.getColor(1, Color.BLACK)
-        typedArray.recycle()
+        val colorAccent = context.getColor(com.android.internal.R.color.materialColorPrimaryFixed)
+        val shapeColor = context.getColor(com.android.internal.R.color.materialColorOnPrimaryFixed)
 
         dotColor = colorAccent
         overflowBtn?.iconDrawable?.setTint(shapeColor)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
index bf98ef8..64f54b8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
@@ -226,13 +226,11 @@
                         ? res.getColor(R.color.bubbles_dark)
                         : res.getColor(R.color.bubbles_light));
 
-        final TypedArray typedArray = getContext().obtainStyledAttributes(new int[] {
-                com.android.internal.R.attr.materialColorSurfaceBright,
-                com.android.internal.R.attr.materialColorOnSurface});
-        int bgColor = typedArray.getColor(0, isNightMode ? Color.BLACK : Color.WHITE);
-        int textColor = typedArray.getColor(1, isNightMode ? Color.WHITE : Color.BLACK);
-        textColor = ContrastColorUtil.ensureTextContrast(textColor, bgColor, isNightMode);
-        typedArray.recycle();
+
+        int bgColor = getContext().getColor(
+                com.android.internal.R.color.materialColorSurfaceBright);
+        int textColor = getContext().getColor(com.android.internal.R.color.materialColorOnSurface);
+
         setBackgroundColor(bgColor);
         mEmptyStateTitle.setTextColor(textColor);
         mEmptyStateSubtitle.setTextColor(textColor);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePopupViewExt.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePopupViewExt.kt
index 9b3054e..a65466f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePopupViewExt.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePopupViewExt.kt
@@ -15,7 +15,6 @@
  */
 package com.android.wm.shell.bubbles
 
-import android.graphics.Color
 import com.android.wm.shell.R
 import com.android.wm.shell.shared.bubbles.BubblePopupDrawable
 import com.android.wm.shell.shared.bubbles.BubblePopupView
@@ -27,7 +26,6 @@
     val attrs =
         context.obtainStyledAttributes(
             intArrayOf(
-                com.android.internal.R.attr.materialColorSurfaceContainer,
                 android.R.attr.dialogCornerRadius
             )
         )
@@ -35,8 +33,8 @@
     val res = context.resources
     val config =
         BubblePopupDrawable.Config(
-            color = attrs.getColor(0, Color.WHITE),
-            cornerRadius = attrs.getDimension(1, 0f),
+            color = context.getColor(com.android.internal.R.color.materialColorSurfaceContainer),
+            cornerRadius = attrs.getDimension(0, 0f),
             contentPadding = res.getDimensionPixelSize(R.dimen.bubble_popup_padding),
             arrowWidth = res.getDimension(R.dimen.bubble_popup_arrow_width),
             arrowHeight = res.getDimension(R.dimen.bubble_popup_arrow_height),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index 0fd4206..de85d9a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -163,8 +163,11 @@
             mExpandedViewLargeScreenWidth = (int) (bounds.width()
                     * EXPANDED_VIEW_SMALL_TABLET_WIDTH_PERCENT);
         } else {
-            mExpandedViewLargeScreenWidth =
-                    res.getDimensionPixelSize(R.dimen.bubble_expanded_view_largescreen_width);
+            int expandedViewLargeScreenSpacing = res.getDimensionPixelSize(
+                    R.dimen.bubble_expanded_view_largescreen_landscape_padding);
+            mExpandedViewLargeScreenWidth = Math.min(
+                    res.getDimensionPixelSize(R.dimen.bubble_expanded_view_largescreen_width),
+                    bounds.width() - expandedViewLargeScreenSpacing * 2);
         }
         if (mDeviceConfig.isLargeScreen()) {
             if (mDeviceConfig.isSmallTablet()) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 88f55b8..249a218 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -40,7 +40,6 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
-import android.graphics.Color;
 import android.graphics.Outline;
 import android.graphics.PointF;
 import android.graphics.PorterDuff;
@@ -1326,10 +1325,9 @@
                 R.layout.bubble_manage_menu, this, false);
         mManageMenu.setVisibility(View.INVISIBLE);
 
-        final TypedArray ta = mContext.obtainStyledAttributes(new int[]{
-                com.android.internal.R.attr.materialColorSurfaceBright});
-        final int menuBackgroundColor = ta.getColor(0, Color.WHITE);
-        ta.recycle();
+        final int menuBackgroundColor = mContext.getColor(
+                com.android.internal.R.color.materialColorSurfaceBright);
+
         mManageMenu.getBackground().setColorFilter(menuBackgroundColor, PorterDuff.Mode.SRC_IN);
 
         PhysicsAnimator.getInstance(mManageMenu).setDefaultSpringConfig(mManageSpringConfig);
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 4d7c7fa..3e8a9b6 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
@@ -272,6 +272,7 @@
         final float startTx = getSwitchAnimationInitialTx(endTx);
         toBbev.setTranslationX(startTx);
         toBbev.getHandleView().setAlpha(0f);
+        toBbev.getHandleView().setHandleInitialColor(fromBbev.getHandleView().getHandleColor());
 
         toBbev.animateExpansionWhenTaskViewVisible(() -> {
             AnimatorSet switchAnim = new AnimatorSet();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
index 2c0483c..65c929a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
@@ -606,6 +606,11 @@
         mTaskView.setZOrderedOnTop(onTop, true /* allowDynamicChange */);
     }
 
+    @VisibleForTesting
+    boolean isSurfaceZOrderedOnTop() {
+        return mTaskView != null && mTaskView.isZOrderedOnTop();
+    }
+
     /**
      * Sets whether the view is animating, in this case we won't change the content visibility
      * until the animation is done.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
index 712e41b..9cf0d2d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
@@ -65,6 +65,7 @@
     @Nullable
     private ObjectAnimator mColorChangeAnim;
     private @ColorInt int mRegionSamplerColor;
+    private boolean mHasSampledColor;
 
     public BubbleBarHandleView(Context context) {
         this(context, null /* attrs */);
@@ -102,7 +103,11 @@
         invalidate();
     }
 
-    private int getHandleColor() {
+    /**
+     * Get current color value for the handle
+     */
+    @ColorInt
+    public int getHandleColor() {
         return mHandlePaint.getColor();
     }
 
@@ -128,6 +133,16 @@
     }
 
     /**
+     * Set initial color for the handle. Takes effect if the
+     * {@link #updateHandleColor(boolean, boolean)} has not been called.
+     */
+    public void setHandleInitialColor(@ColorInt int color) {
+        if (!mHasSampledColor) {
+            setHandleColor(color);
+        }
+    }
+
+    /**
      * Updates the handle color.
      *
      * @param isRegionDark Whether the background behind the handle is dark, and thus the handle
@@ -139,6 +154,7 @@
         if (newColor == mRegionSamplerColor) {
             return;
         }
+        mHasSampledColor = true;
         mRegionSamplerColor = newColor;
         if (mColorChangeAnim != null) {
             mColorChangeAnim.cancel();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuItemView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuItemView.java
index 1c71ef4..6c14d83 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuItemView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuItemView.java
@@ -17,7 +17,6 @@
 
 import android.annotation.ColorInt;
 import android.content.Context;
-import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.drawable.Icon;
 import android.util.AttributeSet;
@@ -63,9 +62,8 @@
      */
     void update(Icon icon, String title, @ColorInt int tint) {
         if (tint == Color.TRANSPARENT) {
-            final TypedArray typedArray = getContext().obtainStyledAttributes(
-                    new int[]{com.android.internal.R.attr.materialColorOnSurface});
-            mTextView.setTextColor(typedArray.getColor(0, Color.BLACK));
+            mTextView.setTextColor(
+                    getContext().getColor(com.android.internal.R.color.materialColorOnSurface));
         } else {
             icon.setTint(tint);
             mTextView.setTextColor(tint);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
index 99e2009..dfbf655 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
@@ -18,7 +18,6 @@
 import android.annotation.ColorInt;
 import android.content.Context;
 import android.content.res.ColorStateList;
-import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.drawable.Icon;
 import android.util.AttributeSet;
@@ -91,14 +90,11 @@
     }
 
     private void updateThemeColors() {
-        try (TypedArray ta = mContext.obtainStyledAttributes(new int[]{
-                com.android.internal.R.attr.materialColorSurfaceBright,
-                com.android.internal.R.attr.materialColorOnSurface
-        })) {
-            mActionsSectionView.getBackground().setTint(ta.getColor(0, Color.WHITE));
-            ImageViewCompat.setImageTintList(mBubbleDismissIconView,
-                    ColorStateList.valueOf(ta.getColor(1, Color.BLACK)));
-        }
+        mActionsSectionView.getBackground().setTint(
+                mContext.getColor(com.android.internal.R.color.materialColorSurfaceBright));
+        ImageViewCompat.setImageTintList(mBubbleDismissIconView,
+                ColorStateList.valueOf(
+                        mContext.getColor(com.android.internal.R.color.materialColorOnSurface)));
     }
 
     /** Animates the menu from the specified start scale. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
index 9dd0cae..5f437d4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
@@ -22,8 +22,6 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Color;
 import android.graphics.drawable.Icon;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -169,12 +167,7 @@
         int handleHeight = mHandleView.getHandleHeight();
         float targetWidth = mHandleView.getHandleWidth() + widthDiff * WIDTH_SWAP_FRACTION;
         float targetHeight = targetWidth * mMenuView.getTitleItemHeight() / mMenuView.getWidth();
-        int menuColor;
-        try (TypedArray ta = mContext.obtainStyledAttributes(new int[]{
-                com.android.internal.R.attr.materialColorSurfaceBright,
-        })) {
-            menuColor = ta.getColor(0, Color.WHITE);
-        }
+        int menuColor = mContext.getColor(com.android.internal.R.color.materialColorSurfaceBright);
         // Calculating deltas
         float swapScale = targetWidth / mMenuView.getWidth();
         float handleWidthDelta = targetWidth - mHandleView.getHandleWidth();
@@ -227,11 +220,8 @@
     private ArrayList<BubbleBarMenuView.MenuAction> createMenuActions(Bubble bubble) {
         ArrayList<BubbleBarMenuView.MenuAction> menuActions = new ArrayList<>();
         Resources resources = mContext.getResources();
-        int tintColor;
-        try (TypedArray ta = mContext.obtainStyledAttributes(new int[]{
-                com.android.internal.R.attr.materialColorOnSurface})) {
-            tintColor = ta.getColor(0, Color.TRANSPARENT);
-        }
+        int tintColor = mContext.getColor(com.android.internal.R.color.materialColorOnSurface);
+
         if (bubble.isConversation()) {
             // Don't bubble conversation action
             menuActions.add(new BubbleBarMenuView.MenuAction(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
index ec3c0b8..c74bf53 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
@@ -338,6 +338,11 @@
             // Make mImeSourceControl point to the new control before starting the animation.
             if (hadImeSourceControl && mImeSourceControl != imeSourceControl) {
                 mImeSourceControl.release(SurfaceControl::release);
+                if (android.view.inputmethod.Flags.refactorInsetsController()
+                        && !hasImeLeash && mAnimation != null) {
+                    // In case of losing the leash, the animation should be cancelled.
+                    mAnimation.cancel();
+                }
             }
             mImeSourceControl = imeSourceControl;
 
@@ -414,9 +419,14 @@
                 // already (e.g., when focussing an editText in activity B, while and editText in
                 // activity A is focussed), we will not get a call of #insetsControlChanged, and
                 // therefore have to start the show animation from here
-                startAnimation(mImeRequestedVisible /* show */, false /* forceRestart */);
+                startAnimation(mImeRequestedVisible /* show */, false /* forceRestart */,
+                        statsToken);
 
-                setVisibleDirectly(mImeRequestedVisible || mAnimation != null, statsToken);
+                // In case of a hide, the statsToken should not been send yet (as the animation
+                // is still ongoing). It will be sent at the end of the animation
+                boolean hideAnimOngoing = !mImeRequestedVisible && mAnimation != null;
+                setVisibleDirectly(mImeRequestedVisible || mAnimation != null,
+                        hideAnimOngoing ? null : statsToken);
             }
         }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java
index 813772f..2f5afca 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java
@@ -352,8 +352,8 @@
                 ? mPinnedTaskbarInsets.right : mPinnedTaskbarInsets.bottom;
 
         float ratio = areOffscreenRatiosSupported()
-                ? SplitLayout.OFFSCREEN_ASYMMETRIC_RATIO
-                : SplitLayout.ONSCREEN_ONLY_ASYMMETRIC_RATIO;
+                ? SplitSpec.OFFSCREEN_ASYMMETRIC_RATIO
+                : SplitSpec.ONSCREEN_ONLY_ASYMMETRIC_RATIO;
         int size = (int) (ratio * (end - start)) - mDividerSize / 2;
 
         int leftTopPosition = start + pinnedTaskbarShiftStart + size;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
index d20ad5d..9fb36b3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
@@ -33,12 +33,14 @@
 import android.animation.ValueAnimator;
 import android.app.ActivityManager;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.Color;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Binder;
+import android.os.Trace;
 import android.view.IWindow;
 import android.view.LayoutInflater;
 import android.view.SurfaceControl;
@@ -50,10 +52,12 @@
 import android.widget.ImageView;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.ScreenshotUtils;
+import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SurfaceUtils;
 
 import java.util.function.Consumer;
@@ -79,9 +83,19 @@
     private static final String RESIZING_BACKGROUND_SURFACE_NAME = "ResizingBackground";
     private static final String GAP_BACKGROUND_SURFACE_NAME = "GapBackground";
 
+    // Indicates the loading state of mIcon
+    enum IconLoadState {
+        NOT_LOADED,
+        LOADING,
+        LOADED
+    }
+
     private final IconProvider mIconProvider;
+    private final ShellExecutor mMainExecutor;
+    private final ShellExecutor mBgExecutor;
 
     private Drawable mIcon;
+    private IconLoadState mIconLoadState = IconLoadState.NOT_LOADED;
     private ImageView mVeilIconView;
     private SurfaceControlViewHost mViewHost;
     /** The parent surface that this is attached to. Should be the stage root. */
@@ -109,9 +123,14 @@
     private int mOffsetY;
     private int mRunningAnimationCount = 0;
 
-    public SplitDecorManager(Configuration configuration, IconProvider iconProvider) {
+    public SplitDecorManager(Configuration configuration,
+            IconProvider iconProvider,
+            ShellExecutor mainExecutor,
+            ShellExecutor bgExecutor) {
         super(configuration, null /* rootSurface */, null /* hostInputToken */);
         mIconProvider = iconProvider;
+        mMainExecutor = mainExecutor;
+        mBgExecutor = bgExecutor;
     }
 
     @Override
@@ -199,6 +218,7 @@
         }
         mHostLeash = null;
         mIcon = null;
+        mIconLoadState = IconLoadState.NOT_LOADED;
         mVeilIconView = null;
         mIsCurrentlyChanging = false;
         mShown = false;
@@ -260,10 +280,11 @@
                     .setWindowCrop(mGapBackgroundLeash, sideBounds.width(), sideBounds.height());
         }
 
-        if (mIcon == null && resizingTask.topActivityInfo != null) {
-            mIcon = mIconProvider.getIcon(resizingTask.topActivityInfo);
-            mVeilIconView.setImageDrawable(mIcon);
-            mVeilIconView.setVisibility(View.VISIBLE);
+        if (mIconLoadState == IconLoadState.NOT_LOADED && resizingTask.topActivityInfo != null) {
+            loadIconInBackground(resizingTask.topActivityInfo, () -> {
+                mVeilIconView.setImageDrawable(mIcon);
+                mVeilIconView.setVisibility(View.VISIBLE);
+            });
 
             WindowManager.LayoutParams lp =
                     (WindowManager.LayoutParams) mViewHost.getView().getLayoutParams();
@@ -417,10 +438,10 @@
         }
 
         if (mIcon == null && resizingTask.topActivityInfo != null) {
-            // Initialize icon
-            mIcon = mIconProvider.getIcon(resizingTask.topActivityInfo);
-            mVeilIconView.setImageDrawable(mIcon);
-            mVeilIconView.setVisibility(View.VISIBLE);
+            loadIconInBackground(resizingTask.topActivityInfo, () -> {
+                mVeilIconView.setImageDrawable(mIcon);
+                mVeilIconView.setVisibility(View.VISIBLE);
+            });
 
             WindowManager.LayoutParams lp =
                     (WindowManager.LayoutParams) mViewHost.getView().getLayoutParams();
@@ -453,7 +474,7 @@
             return;
         }
 
-        // Recenter icon
+        // Re-center icon
         t.setPosition(mIconLeash,
                 mInstantaneousBounds.width() / 2f - mIconSize / 2f,
                 mInstantaneousBounds.height() / 2f - mIconSize / 2f);
@@ -596,9 +617,38 @@
             mVeilIconView.setImageDrawable(null);
             t.hide(mIconLeash);
             mIcon = null;
+            mIconLoadState = IconLoadState.NOT_LOADED;
         }
     }
 
+    /**
+     * Loads the icon for the given {@param info}, calling {@param postLoadCb} on the main thread
+     * if provided.
+     */
+    private void loadIconInBackground(@NonNull ActivityInfo info, @Nullable Runnable postLoadCb) {
+        mIconLoadState = IconLoadState.LOADING;
+        mBgExecutor.setBoost();
+        mBgExecutor.execute(() -> {
+            Trace.beginSection("SplitDecorManager.loadIconInBackground("
+                    + info.applicationInfo.packageName + ")");
+            final Drawable icon = mIconProvider.getIcon(info);
+            Trace.endSection();
+            mMainExecutor.execute(() -> {
+                if (mIconLoadState != IconLoadState.LOADING) {
+                    // The request was canceled while loading in the background, just drop the
+                    // result
+                    return;
+                }
+                mIcon = icon;
+                mIconLoadState = IconLoadState.LOADED;
+                if (postLoadCb != null) {
+                    postLoadCb.run();
+                }
+            });
+            mBgExecutor.resetBoost();
+        });
+    }
+
     private static float[] getResizingBackgroundColor(ActivityManager.RunningTaskInfo taskInfo) {
         final int taskBgColor = taskInfo.taskDescription.getBackgroundColor();
         return Color.valueOf(taskBgColor == -1 ? Color.WHITE : taskBgColor).getComponents();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index 1852cda..21c44c9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -112,11 +112,6 @@
     private static final int FLING_EXIT_DURATION = 450;
     private static final int FLING_OFFSCREEN_DURATION = 500;
 
-    /** A split ratio used on larger screens, where we can fit both apps onscreen. */
-    public static final float ONSCREEN_ONLY_ASYMMETRIC_RATIO = 0.33f;
-    /** A split ratio used on smaller screens, where we place one app mostly offscreen. */
-    public static final float OFFSCREEN_ASYMMETRIC_RATIO = 0.1f;
-
     // Here are some (arbitrarily decided) layer definitions used during animations to make sure the
     // layers stay in order. (During transitions, everything is reparented onto a transition root
     // and can be freely relayered.)
@@ -236,7 +231,7 @@
         updateDividerConfig(mContext);
 
         mRootBounds.set(configuration.windowConfiguration.getBounds());
-        mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
+        updateLayouts();
         mInteractionJankMonitor = InteractionJankMonitor.getInstance();
         resetDividerPosition();
         updateInvisibleRect();
@@ -490,7 +485,7 @@
         mIsLargeScreen = configuration.smallestScreenWidthDp >= 600;
         mIsLeftRightSplit = SplitScreenUtils.isLeftRightSplit(mAllowLeftRightSplitInPortrait,
                 configuration);
-        mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
+        updateLayouts();
         updateDividerConfig(mContext);
         initDividerPosition(mTempRect, wasLeftRightSplit);
         updateInvisibleRect();
@@ -518,7 +513,7 @@
         mRootBounds.set(tmpRect);
         mIsLeftRightSplit = SplitScreenUtils.isLeftRightSplit(mAllowLeftRightSplitInPortrait,
                 mIsLargeScreen, mRootBounds.width() >= mRootBounds.height());
-        mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
+        updateLayouts();
         initDividerPosition(mTempRect, wasLeftRightSplit);
     }
 
@@ -652,7 +647,7 @@
         if (!mPinnedTaskbarInsets.equals(pinnedTaskbarInsets)) {
             mPinnedTaskbarInsets = pinnedTaskbarInsets;
             // Refresh the DividerSnapAlgorithm.
-            mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
+            updateLayouts();
             // If the divider is no longer placed on a snap point, animate it to the nearest one.
             DividerSnapAlgorithm.SnapTarget snapTarget =
                     findSnapTarget(mDividerPosition, 0, false /* hardDismiss */);
@@ -799,6 +794,10 @@
     }
 
     void onStartDragging() {
+        // This triggers initialization of things like the resize veil in preparation for
+        // showing it when the user moves the divider past the slop
+        updateDividerBounds(getDividerPosition(), false /* shouldUseParallaxEffect */);
+
         mInteractionJankMonitor.begin(getDividerLeash(), mContext, mHandler,
                 CUJ_SPLIT_SCREEN_RESIZE);
     }
@@ -824,8 +823,22 @@
         return mDividerSnapAlgorithm.calculateSnapTarget(position, velocity, hardDismiss);
     }
 
-    private DividerSnapAlgorithm getSnapAlgorithm(Context context, Rect rootBounds) {
-        final Rect insets = getDisplayStableInsets(context);
+    /**
+     * (Re)calculates the split screen logic for this particular display/orientation. Refreshes the
+     * DividerSnapAlgorithm, which controls divider snap points, and populates a map in SplitState
+     * with bounds for all valid split layouts.
+     */
+    private void updateLayouts() {
+        // Update SplitState map
+
+        if (Flags.enableFlexibleTwoAppSplit()) {
+            mSplitState.populateLayouts(
+                    mRootBounds, mDividerSize, mIsLeftRightSplit, mPinnedTaskbarInsets.toRect());
+        }
+
+        // Get new DividerSnapAlgorithm
+
+        final Rect insets = getDisplayStableInsets(mContext);
 
         // Make split axis insets value same as the larger one to avoid bounds1 and bounds2
         // have difference for avoiding size-compat mode when switching unresizable apps in
@@ -835,10 +848,10 @@
             insets.set(insets.left, largerInsets, insets.right, largerInsets);
         }
 
-        return new DividerSnapAlgorithm(
-                context.getResources(),
-                rootBounds.width(),
-                rootBounds.height(),
+        mDividerSnapAlgorithm = new DividerSnapAlgorithm(
+                mContext.getResources(),
+                mRootBounds.width(),
+                mRootBounds.height(),
                 mDividerSize,
                 mIsLeftRightSplit,
                 insets,
@@ -1560,7 +1573,9 @@
             final int imeTargetPosition = getImeTargetPosition();
             mHasImeFocus = imeTargetPosition != SPLIT_POSITION_UNDEFINED;
             if (!mHasImeFocus) {
-                return 0;
+                if (!android.view.inputmethod.Flags.refactorInsetsController() || showing) {
+                    return 0;
+                }
             }
 
             mStartImeTop = showing ? hiddenTop : shownTop;
@@ -1613,7 +1628,11 @@
 
         @Override
         public void onImePositionChanged(int displayId, int imeTop, SurfaceControl.Transaction t) {
-            if (displayId != mDisplayId || !mHasImeFocus) return;
+            if (displayId != mDisplayId || !mHasImeFocus) {
+                if (!android.view.inputmethod.Flags.refactorInsetsController() || mImeShown) {
+                    return;
+                }
+            }
             onProgress(getProgress(imeTop));
             mSplitLayoutHandler.onLayoutPositionChanging(SplitLayout.this);
         }
@@ -1621,7 +1640,12 @@
         @Override
         public void onImeEndPositioning(int displayId, boolean cancel,
                 SurfaceControl.Transaction t) {
-            if (displayId != mDisplayId || !mHasImeFocus || cancel) return;
+            if (displayId != mDisplayId || cancel) return;
+            if (!mHasImeFocus) {
+                if (!android.view.inputmethod.Flags.refactorInsetsController() || mImeShown) {
+                    return;
+                }
+            }
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
                     "Split IME animation ending, canceled=%b", cancel);
             onProgress(1.0f);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitSpec.java
new file mode 100644
index 0000000..9c951bd
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitSpec.java
@@ -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.wm.shell.common.split;
+
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_10_90;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_33_66;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_66_33;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_90_10;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_3_10_45_45;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_3_33_33_33;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_3_45_45_10;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.stateToString;
+
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.util.Log;
+
+import com.android.wm.shell.shared.split.SplitScreenConstants.SplitScreenState;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A reference class that stores the split layouts available in this device/orientation. Layouts are
+ * available as lists of RectFs, where each RectF represents the bounds of an app.
+ */
+public class SplitSpec {
+    private static final String TAG = "SplitSpec";
+    private static final boolean DEBUG = true;
+
+    /** A split ratio used on larger screens, where we can fit both apps onscreen. */
+    public static final float ONSCREEN_ONLY_ASYMMETRIC_RATIO = 0.33f;
+    /** A split ratio used on smaller screens, where we place one app mostly offscreen. */
+    public static final float OFFSCREEN_ASYMMETRIC_RATIO = 0.1f;
+    /** A 50-50 split ratio. */
+    public static final float MIDDLE_RATIO = 0.5f;
+
+    private final boolean mIsLeftRightSplit;
+    /** The usable display area, considering insets that affect split bounds. */
+    private final RectF mUsableArea;
+    /** Half the divider size. */
+    private final float mHalfDiv;
+
+    /** A large map that stores all valid split layouts. */
+    private final Map<Integer, List<RectF>> mLayouts = new HashMap<>();
+
+    /** Constructor; initializes the layout map. */
+    public SplitSpec(Rect displayBounds, int dividerSize, boolean isLeftRightSplit,
+            Rect pinnedTaskbarInsets) {
+        mIsLeftRightSplit = isLeftRightSplit;
+        mUsableArea = new RectF(displayBounds);
+        mUsableArea.left += pinnedTaskbarInsets.left;
+        mUsableArea.top += pinnedTaskbarInsets.top;
+        mUsableArea.right -= pinnedTaskbarInsets.right;
+        mUsableArea.bottom -= pinnedTaskbarInsets.bottom;
+        mHalfDiv = dividerSize / 2f;
+
+        // The "start" position, considering insets.
+        float s = isLeftRightSplit ? mUsableArea.left : mUsableArea.top;
+        // The "end" position, considering insets.
+        float e = isLeftRightSplit ? mUsableArea.right : mUsableArea.bottom;
+        // The "length" of the usable display (width or height). Apps are arranged along this axis.
+        float l = e - s;
+        float divPos;
+        float divPos2;
+
+        // SNAP_TO_2_10_90
+        divPos = s + (l * OFFSCREEN_ASYMMETRIC_RATIO);
+        createAppLayout(SNAP_TO_2_10_90, divPos);
+
+        // SNAP_TO_2_33_66
+        divPos = s + (l * ONSCREEN_ONLY_ASYMMETRIC_RATIO);
+        createAppLayout(SNAP_TO_2_33_66, divPos);
+
+        // SNAP_TO_2_50_50
+        divPos = s + (l * MIDDLE_RATIO);
+        createAppLayout(SNAP_TO_2_50_50, divPos);
+
+        // SNAP_TO_2_66_33
+        divPos = s + (l * (1 - ONSCREEN_ONLY_ASYMMETRIC_RATIO));
+        createAppLayout(SNAP_TO_2_66_33, divPos);
+
+        // SNAP_TO_2_90_10
+        divPos = s + (l * (1 - OFFSCREEN_ASYMMETRIC_RATIO));
+        createAppLayout(SNAP_TO_2_90_10, divPos);
+
+        // SNAP_TO_3_10_45_45
+        divPos = s + (l * OFFSCREEN_ASYMMETRIC_RATIO);
+        divPos2 = e - ((l * (1 - OFFSCREEN_ASYMMETRIC_RATIO)) / 2f);
+        createAppLayout(SNAP_TO_3_10_45_45, divPos, divPos2);
+
+        // SNAP_TO_3_33_33_33
+        divPos = s + (l * ONSCREEN_ONLY_ASYMMETRIC_RATIO);
+        divPos2 = e - (l * ONSCREEN_ONLY_ASYMMETRIC_RATIO);
+        createAppLayout(SNAP_TO_3_33_33_33, divPos, divPos2);
+
+        // SNAP_TO_3_45_45_10
+        divPos = s + ((l * (1 - OFFSCREEN_ASYMMETRIC_RATIO)) / 2f);
+        divPos2 = e - (l * OFFSCREEN_ASYMMETRIC_RATIO);
+        createAppLayout(SNAP_TO_3_45_45_10, divPos, divPos2);
+
+        if (DEBUG) {
+            dump();
+        }
+    }
+
+    /**
+     * Creates a two-app layout and enters it into the layout map.
+     * @param divPos The position of the divider.
+     */
+    private void createAppLayout(@SplitScreenState int state, float divPos) {
+        List<RectF> list = new ArrayList<>();
+        RectF rect1 = new RectF(mUsableArea);
+        RectF rect2 = new RectF(mUsableArea);
+        if (mIsLeftRightSplit) {
+            rect1.right = divPos - mHalfDiv;
+            rect2.left = divPos + mHalfDiv;
+        } else {
+            rect1.top = divPos - mHalfDiv;
+            rect2.bottom = divPos + mHalfDiv;
+        }
+        list.add(rect1);
+        list.add(rect2);
+        mLayouts.put(state, list);
+    }
+
+    /**
+     * Creates a three-app layout and enters it into the layout map.
+     * @param divPos1 The position of the first divider.
+     * @param divPos2 The position of the second divider.
+     */
+    private void createAppLayout(@SplitScreenState int state, float divPos1, float divPos2) {
+        List<RectF> list = new ArrayList<>();
+        RectF rect1 = new RectF(mUsableArea);
+        RectF rect2 = new RectF(mUsableArea);
+        RectF rect3 = new RectF(mUsableArea);
+        if (mIsLeftRightSplit) {
+            rect1.right = divPos1 - mHalfDiv;
+            rect2.left = divPos1 + mHalfDiv;
+            rect2.right = divPos2 - mHalfDiv;
+            rect3.left = divPos2 + mHalfDiv;
+        } else {
+            rect1.right = divPos1 - mHalfDiv;
+            rect2.left = divPos1 + mHalfDiv;
+            rect3.right = divPos2 - mHalfDiv;
+            rect3.left = divPos2 + mHalfDiv;
+        }
+        list.add(rect1);
+        list.add(rect2);
+        list.add(rect3);
+        mLayouts.put(state, list);
+    }
+
+    /** Logs all calculated layouts */
+    private void dump() {
+        mLayouts.forEach((k, v) -> {
+            Log.d(TAG, stateToString(k));
+            v.forEach(rect -> Log.d(TAG, " - " + rect.toShortString()));
+        });
+    }
+
+    /** Returns the layout associated with a given split state. */
+    List<RectF> getSpec(@SplitScreenState int state) {
+        return mLayouts.get(state);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitState.java
index 71758e0..d1d133d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitState.java
@@ -19,11 +19,17 @@
 import static com.android.wm.shell.shared.split.SplitScreenConstants.NOT_IN_SPLIT;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.SplitScreenState;
 
+import android.graphics.Rect;
+import android.graphics.RectF;
+
+import java.util.List;
+
 /**
  * A class that manages the "state" of split screen. See {@link SplitScreenState} for definitions.
  */
 public class SplitState {
     private @SplitScreenState int mState = NOT_IN_SPLIT;
+    private SplitSpec mSplitSpec;
 
     /** Updates the current state of split screen on this device. */
     public void set(@SplitScreenState int newState) {
@@ -39,4 +45,16 @@
     public void exit() {
         set(NOT_IN_SPLIT);
     }
+
+    /** Refresh the valid layouts for this display/orientation. */
+    public void populateLayouts(Rect displayBounds, int dividerSize, boolean isLeftRightSplit,
+            Rect pinnedTaskbarInsets) {
+        mSplitSpec =
+                new SplitSpec(displayBounds, dividerSize, isLeftRightSplit, pinnedTaskbarInsets);
+    }
+
+    /** Returns the layout associated with a given split state. */
+    public List<RectF> getLayout(@SplitScreenState int state) {
+        return mSplitSpec.getSpec(state);
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
index 9d4b4bb..fe6066c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
@@ -55,6 +55,7 @@
 import com.android.wm.shell.compatui.api.CompatUIInfo;
 import com.android.wm.shell.compatui.impl.CompatUIEvents.SizeCompatRestartButtonClicked;
 import com.android.wm.shell.desktopmode.DesktopUserRepositories;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.sysui.KeyguardChangeListener;
 import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.sysui.ShellInit;
@@ -70,7 +71,6 @@
 import java.util.Set;
 import java.util.function.Consumer;
 import java.util.function.Function;
-import java.util.function.IntPredicate;
 import java.util.function.Predicate;
 
 /**
@@ -667,9 +667,10 @@
 
     private void createOrUpdateUserAspectRatioSettingsLayout(@NonNull TaskInfo taskInfo,
             @Nullable ShellTaskOrganizer.TaskListener taskListener) {
+        boolean overridesShowAppHandle = DesktopModeStatus.overridesShowAppHandle(mContext);
         if (mUserAspectRatioSettingsLayout != null) {
             if (mUserAspectRatioSettingsLayout.needsToBeRecreated(taskInfo, taskListener)
-                    || mIsInDesktopMode) {
+                    || mIsInDesktopMode || overridesShowAppHandle) {
                 mUserAspectRatioSettingsLayout.release();
                 mUserAspectRatioSettingsLayout = null;
             } else {
@@ -682,8 +683,9 @@
                 return;
             }
         }
-        if (mIsInDesktopMode) {
-            // Return if in desktop mode.
+        if (mIsInDesktopMode || overridesShowAppHandle) {
+            // Return if in desktop mode or app handle menu is already showing change aspect ratio
+            // option.
             return;
         }
         // Create a new UI layout.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxUtils.kt
index ef964f4..8e149ac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxUtils.kt
@@ -66,3 +66,41 @@
         other.dump()
     }
 }
+
+object LetterboxUtils {
+    // Utility methods about Maps usage in Letterbox.
+    object Maps {
+        /*
+         * Executes [onFound] on the [item] for a given [key] if present or
+         * [onMissed] if the [key] is not present.
+         */
+        fun <V, K> MutableMap<K, V>.runOnItem(
+            key: K,
+            onFound: (V) -> Unit = { _ -> },
+            onMissed: (
+                K,
+                MutableMap<K, V>
+            ) -> Unit = { _, _ -> }
+        ) {
+            this[key]?.let {
+                return onFound(it)
+            }
+            return onMissed(key, this)
+        }
+    }
+
+    // Utility methods about Transaction usage in Letterbox.
+    object Transactions {
+        // Sets position and crops in one method.
+        fun Transaction.moveAndCrop(
+            surface: SurfaceControl,
+            rect: Rect
+        ): Transaction =
+            setPosition(surface, rect.left.toFloat(), rect.top.toFloat())
+                .setWindowCrop(
+                    surface,
+                    rect.width(),
+                    rect.height()
+                )
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/MultiSurfaceLetterboxController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/MultiSurfaceLetterboxController.kt
index 5129d03..6861aa3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/MultiSurfaceLetterboxController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/MultiSurfaceLetterboxController.kt
@@ -20,6 +20,8 @@
 import android.view.SurfaceControl
 import android.view.SurfaceControl.Transaction
 import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.compatui.letterbox.LetterboxUtils.Maps.runOnItem
+import com.android.wm.shell.compatui.letterbox.LetterboxUtils.Transactions.moveAndCrop
 import com.android.wm.shell.dagger.WMSingleton
 import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_APP_COMPAT
 import javax.inject.Inject
@@ -101,23 +103,6 @@
         ProtoLog.v(WM_SHELL_APP_COMPAT, "%s: %s", TAG, "${letterboxMap.keys}")
     }
 
-    /*
-     * Executes [onFound] on the [LetterboxItem] if present or [onMissed] if not present.
-     */
-    private fun MutableMap<LetterboxKey, LetterboxSurfaces>.runOnItem(
-        key: LetterboxKey,
-        onFound: (LetterboxSurfaces) -> Unit = { _ -> },
-        onMissed: (
-            LetterboxKey,
-            MutableMap<LetterboxKey, LetterboxSurfaces>
-        ) -> Unit = { _, _ -> }
-    ) {
-        this[key]?.let {
-            return onFound(it)
-        }
-        return onMissed(key, this)
-    }
-
     private fun SurfaceControl?.remove(
         tx: Transaction
     ) = this?.let {
@@ -131,17 +116,6 @@
         tx.setVisibility(this, visible)
     }
 
-    private fun Transaction.moveAndCrop(
-        surface: SurfaceControl,
-        rect: Rect
-    ): Transaction =
-        setPosition(surface, rect.left.toFloat(), rect.top.toFloat())
-            .setWindowCrop(
-                surface,
-                rect.width(),
-                rect.height()
-            )
-
     private fun LetterboxSurfaces.updateSurfacesBounds(
         tx: Transaction,
         taskBounds: Rect,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/SingleSurfaceLetterboxController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/SingleSurfaceLetterboxController.kt
index a67f608..8e1cdee 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/SingleSurfaceLetterboxController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/SingleSurfaceLetterboxController.kt
@@ -20,6 +20,8 @@
 import android.view.SurfaceControl
 import android.view.SurfaceControl.Transaction
 import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.compatui.letterbox.LetterboxUtils.Maps.runOnItem
+import com.android.wm.shell.compatui.letterbox.LetterboxUtils.Transactions.moveAndCrop
 import com.android.wm.shell.dagger.WMSingleton
 import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_APP_COMPAT
 import javax.inject.Inject
@@ -106,32 +108,4 @@
     override fun dump() {
         ProtoLog.v(WM_SHELL_APP_COMPAT, "%s: %s", TAG, "${letterboxMap.keys}")
     }
-
-    /*
-     * Executes [onFound] on the [SurfaceControl] if present or [onMissed] if not present.
-     */
-    private fun MutableMap<LetterboxKey, SurfaceControl>.runOnItem(
-        key: LetterboxKey,
-        onFound: (SurfaceControl) -> Unit = { _ -> },
-        onMissed: (
-            LetterboxKey,
-            MutableMap<LetterboxKey, SurfaceControl>
-        ) -> Unit = { _, _ -> }
-    ) {
-        this[key]?.let {
-            return onFound(it)
-        }
-        return onMissed(key, this)
-    }
-
-    private fun Transaction.moveAndCrop(
-        surface: SurfaceControl,
-        rect: Rect
-    ): Transaction =
-        setPosition(surface, rect.left.toFloat(), rect.top.toFloat())
-            .setWindowCrop(
-                surface,
-                rect.width(),
-                rect.height()
-            )
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java
index aebd94f..5b6b897 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java
@@ -34,6 +34,7 @@
 import com.android.wm.shell.dagger.pip.TvPipModule;
 import com.android.wm.shell.recents.RecentTasksController;
 import com.android.wm.shell.shared.TransactionPool;
+import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 import com.android.wm.shell.splitscreen.tv.TvSplitScreenController;
@@ -93,11 +94,12 @@
             SplitState splitState,
             @ShellMainThread ShellExecutor mainExecutor,
             Handler mainHandler,
+            @ShellBackgroundThread ShellExecutor bgExecutor,
             SystemWindows systemWindows) {
         return new TvSplitScreenController(context, shellInit, shellCommandHandler, shellController,
                 shellTaskOrganizer, syncQueue, rootTDAOrganizer, displayController,
                 displayImeController, displayInsetsController, transitions, transactionPool,
                 iconProvider, recentTasks, launchAdjacentController, multiInstanceHelper,
-                splitState, mainExecutor, mainHandler, systemWindows);
+                splitState, mainExecutor, mainHandler, bgExecutor, systemWindows);
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index f9e3be9..ace7f07 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -151,6 +151,7 @@
 import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel;
 import com.android.wm.shell.windowdecor.WindowDecorViewModel;
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer;
+import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader;
 import com.android.wm.shell.windowdecor.common.viewhost.DefaultWindowDecorViewHostSupplier;
 import com.android.wm.shell.windowdecor.common.viewhost.PooledWindowDecorViewHostSupplier;
 import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost;
@@ -349,10 +350,13 @@
     @Provides
     static WindowDecorViewHostSupplier<WindowDecorViewHost> provideWindowDecorViewHostSupplier(
             @NonNull Context context,
-            @ShellMainThread @NonNull CoroutineScope mainScope) {
+            @ShellMainThread @NonNull CoroutineScope mainScope,
+            @NonNull ShellInit shellInit) {
         final int poolSize = DesktopModeStatus.getWindowDecorScvhPoolSize(context);
+        final int preWarmSize = DesktopModeStatus.getWindowDecorPreWarmSize();
         if (DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context) && poolSize > 0) {
-            return new PooledWindowDecorViewHostSupplier(mainScope, poolSize);
+            return new PooledWindowDecorViewHostSupplier(
+                    context, mainScope, shellInit, poolSize, preWarmSize);
         }
         return new DefaultWindowDecorViewHostSupplier(mainScope);
     }
@@ -514,7 +518,8 @@
             MultiInstanceHelper multiInstanceHelper,
             SplitState splitState,
             @ShellMainThread ShellExecutor mainExecutor,
-            @ShellMainThread Handler mainHandler) {
+            @ShellMainThread Handler mainHandler,
+            @ShellBackgroundThread ShellExecutor bgExecutor) {
         return new SplitScreenController(
                 context,
                 shellInit,
@@ -538,7 +543,8 @@
                 multiInstanceHelper,
                 splitState,
                 mainExecutor,
-                mainHandler);
+                mainHandler,
+                bgExecutor);
     }
 
     //
@@ -764,6 +770,8 @@
     @WMSingleton
     @Provides
     static DesktopTilingDecorViewModel provideDesktopTilingViewModel(Context context,
+            @ShellMainThread MainCoroutineDispatcher mainDispatcher,
+            @ShellBackgroundThread CoroutineScope bgScope,
             DisplayController displayController,
             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
             SyncTransactionQueue syncQueue,
@@ -772,9 +780,12 @@
             ToggleResizeDesktopTaskTransitionHandler toggleResizeDesktopTaskTransitionHandler,
             ReturnToDragStartAnimator returnToDragStartAnimator,
             @DynamicOverride DesktopUserRepositories desktopUserRepositories,
-            DesktopModeEventLogger desktopModeEventLogger) {
+            DesktopModeEventLogger desktopModeEventLogger,
+            WindowDecorTaskResourceLoader windowDecorTaskResourceLoader) {
         return new DesktopTilingDecorViewModel(
                 context,
+                mainDispatcher,
+                bgScope,
                 displayController,
                 rootTaskDisplayAreaOrganizer,
                 syncQueue,
@@ -783,7 +794,8 @@
                 toggleResizeDesktopTaskTransitionHandler,
                 returnToDragStartAnimator,
                 desktopUserRepositories,
-                desktopModeEventLogger
+                desktopModeEventLogger,
+                windowDecorTaskResourceLoader
         );
     }
 
@@ -900,6 +912,8 @@
             @ShellMainThread ShellExecutor shellExecutor,
             @ShellMainThread Handler mainHandler,
             @ShellMainThread Choreographer mainChoreographer,
+            @ShellMainThread MainCoroutineDispatcher mainDispatcher,
+            @ShellBackgroundThread CoroutineScope bgScope,
             @ShellBackgroundThread ShellExecutor bgExecutor,
             ShellInit shellInit,
             ShellCommandHandler shellCommandHandler,
@@ -926,13 +940,15 @@
             Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
             FocusTransitionObserver focusTransitionObserver,
             DesktopModeEventLogger desktopModeEventLogger,
-            DesktopModeUiEventLogger desktopModeUiEventLogger
+            DesktopModeUiEventLogger desktopModeUiEventLogger,
+            WindowDecorTaskResourceLoader taskResourceLoader
     ) {
         if (!DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context)) {
             return Optional.empty();
         }
         return Optional.of(new DesktopModeWindowDecorViewModel(context, shellExecutor, mainHandler,
-                mainChoreographer, bgExecutor, shellInit, shellCommandHandler, windowManager,
+                mainChoreographer, mainDispatcher, bgScope, bgExecutor,
+                shellInit, shellCommandHandler, windowManager,
                 taskOrganizer, desktopUserRepositories, displayController, shellController,
                 displayInsetsController, syncQueue, transitions, desktopTasksController,
                 desktopImmersiveController.get(),
@@ -940,7 +956,18 @@
                 assistContentRequester, windowDecorViewHostSupplier, multiInstanceHelper,
                 desktopTasksLimiter, appHandleEducationController, appToWebEducationController,
                 windowDecorCaptionHandleRepository, activityOrientationChangeHandler,
-                focusTransitionObserver, desktopModeEventLogger, desktopModeUiEventLogger));
+                focusTransitionObserver, desktopModeEventLogger, desktopModeUiEventLogger,
+                taskResourceLoader));
+    }
+
+    @WMSingleton
+    @Provides
+    static WindowDecorTaskResourceLoader provideWindowDecorTaskResourceLoader(
+            @NonNull Context context, @NonNull ShellInit shellInit,
+            @NonNull ShellController shellController,
+            @NonNull ShellCommandHandler shellCommandHandler) {
+        return new WindowDecorTaskResourceLoader(context, shellInit, shellController,
+                shellCommandHandler);
     }
 
     @WMSingleton
@@ -1022,12 +1049,14 @@
     static DesktopUserRepositories provideDesktopUserRepositories(
             Context context,
             ShellInit shellInit,
+            ShellController shellController,
             DesktopPersistentRepository desktopPersistentRepository,
             DesktopRepositoryInitializer desktopRepositoryInitializer,
             @ShellMainThread CoroutineScope mainScope,
             UserManager userManager
     ) {
-        return new DesktopUserRepositories(context, shellInit, desktopPersistentRepository,
+        return new DesktopUserRepositories(context, shellInit, shellController,
+                desktopPersistentRepository,
                 desktopRepositoryInitializer,
                 mainScope, userManager);
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
index 8e2a412..536dc2a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
@@ -74,13 +74,11 @@
         { SurfaceControl.Transaction() },
     )
 
-    @VisibleForTesting var state: TransitionState? = null
-
-    @VisibleForTesting val pendingExternalExitTransitions = mutableListOf<ExternalPendingExit>()
+    @VisibleForTesting val pendingImmersiveTransitions = mutableListOf<PendingTransition>()
 
     /** Whether there is an immersive transition that hasn't completed yet. */
     private val inProgress: Boolean
-        get() = state != null || pendingExternalExitTransitions.isNotEmpty()
+        get() = pendingImmersiveTransitions.isNotEmpty()
 
     private val rectEvaluator = RectEvaluator()
 
@@ -101,20 +99,19 @@
         if (inProgress) {
             logV(
                 "Cannot start entry because transition(s) already in progress: %s",
-                getRunningTransitions(),
+                pendingImmersiveTransitions,
             )
             return
         }
         val wct = WindowContainerTransaction().apply { setBounds(taskInfo.token, Rect()) }
         logV("Moving task ${taskInfo.taskId} into immersive mode")
         val transition = transitions.startTransition(TRANSIT_CHANGE, wct, /* handler= */ this)
-        state =
-            TransitionState(
-                transition = transition,
-                displayId = taskInfo.displayId,
-                taskId = taskInfo.taskId,
-                direction = Direction.ENTER,
-            )
+        addPendingImmersiveTransition(
+            taskId = taskInfo.taskId,
+            displayId = taskInfo.displayId,
+            direction = Direction.ENTER,
+            transition = transition,
+        )
     }
 
     /** Starts a transition to move an immersive task out of immersive. */
@@ -123,7 +120,7 @@
         if (inProgress) {
             logV(
                 "Cannot start exit because transition(s) already in progress: %s",
-                getRunningTransitions(),
+                pendingImmersiveTransitions,
             )
             return
         }
@@ -134,13 +131,12 @@
             }
         logV("Moving task %d out of immersive mode, reason: %s", taskInfo.taskId, reason)
         val transition = transitions.startTransition(TRANSIT_CHANGE, wct, /* handler= */ this)
-        state =
-            TransitionState(
-                transition = transition,
-                displayId = taskInfo.displayId,
-                taskId = taskInfo.taskId,
-                direction = Direction.EXIT,
-            )
+        addPendingImmersiveTransition(
+            taskId = taskInfo.taskId,
+            displayId = taskInfo.displayId,
+            direction = Direction.EXIT,
+            transition = transition,
+        )
     }
 
     /**
@@ -194,7 +190,13 @@
         return ExitResult.Exit(
             exitingTask = immersiveTask,
             runOnTransitionStart = { transition ->
-                addPendingImmersiveExit(immersiveTask, displayId, transition)
+                addPendingImmersiveTransition(
+                    taskId = immersiveTask,
+                    displayId = displayId,
+                    direction = Direction.EXIT,
+                    transition = transition,
+                    animate = false,
+                )
             },
         )
     }
@@ -220,10 +222,12 @@
             return ExitResult.Exit(
                 exitingTask = taskInfo.taskId,
                 runOnTransitionStart = { transition ->
-                    addPendingImmersiveExit(
+                    addPendingImmersiveTransition(
                         taskId = taskInfo.taskId,
                         displayId = taskInfo.displayId,
+                        direction = Direction.EXIT,
                         transition = transition,
+                        animate = false,
                     )
                 },
             )
@@ -233,14 +237,26 @@
 
     /** Whether the [change] in the [transition] is a known immersive change. */
     fun isImmersiveChange(transition: IBinder, change: TransitionInfo.Change): Boolean {
-        return pendingExternalExitTransitions.any {
+        return pendingImmersiveTransitions.any {
             it.transition == transition && it.taskId == change.taskInfo?.taskId
         }
     }
 
-    private fun addPendingImmersiveExit(taskId: Int, displayId: Int, transition: IBinder) {
-        pendingExternalExitTransitions.add(
-            ExternalPendingExit(taskId = taskId, displayId = displayId, transition = transition)
+    private fun addPendingImmersiveTransition(
+        taskId: Int,
+        displayId: Int,
+        direction: Direction,
+        transition: IBinder,
+        animate: Boolean = true,
+    ) {
+        pendingImmersiveTransitions.add(
+            PendingTransition(
+                taskId = taskId,
+                displayId = displayId,
+                direction = direction,
+                transition = transition,
+                animate = animate,
+            )
         )
     }
 
@@ -251,19 +267,17 @@
         finishTransaction: SurfaceControl.Transaction,
         finishCallback: Transitions.TransitionFinishCallback,
     ): Boolean {
-        val state = requireState()
-        check(state.transition == transition) {
-            "Transition $transition did not match expected state=$state"
-        }
+        val immersiveTransition = getImmersiveTransition(transition) ?: return false
+        if (!immersiveTransition.animate) return false
         logD("startAnimation transition=%s", transition)
         animateResize(
-            targetTaskId = state.taskId,
+            targetTaskId = immersiveTransition.taskId,
             info = info,
             startTransaction = startTransaction,
             finishTransaction = finishTransaction,
             finishCallback = {
                 finishCallback.onTransitionFinished(/* wct= */ null)
-                clearState()
+                pendingImmersiveTransitions.remove(immersiveTransition)
             },
         )
         return true
@@ -346,18 +360,6 @@
         request: TransitionRequestInfo,
     ): WindowContainerTransaction? = null
 
-    override fun onTransitionConsumed(
-        transition: IBinder,
-        aborted: Boolean,
-        finishTransaction: SurfaceControl.Transaction?,
-    ) {
-        val state = this.state ?: return
-        if (transition == state.transition && aborted) {
-            clearState()
-        }
-        super.onTransitionConsumed(transition, aborted, finishTransaction)
-    }
-
     /**
      * Called when any transition in the system is ready to play. This is needed to update the
      * repository state before window decorations are drawn (which happens immediately after
@@ -371,67 +373,42 @@
         finishTransaction: SurfaceControl.Transaction,
     ) {
         val desktopRepository: DesktopRepository = desktopUserRepositories.current
-        // Check if this is a pending external exit transition.
-        val pendingExit =
-            pendingExternalExitTransitions.firstOrNull { pendingExit ->
-                pendingExit.transition == transition
-            }
-        if (pendingExit != null) {
-            if (info.hasTaskChange(taskId = pendingExit.taskId)) {
-                if (desktopRepository.isTaskInFullImmersiveState(pendingExit.taskId)) {
-                    logV("Pending external exit for task#%d verified", pendingExit.taskId)
-                    desktopRepository.setTaskInFullImmersiveState(
-                        displayId = pendingExit.displayId,
-                        taskId = pendingExit.taskId,
-                        immersive = false,
-                    )
-                    if (Flags.enableRestoreToPreviousSizeFromDesktopImmersive()) {
-                        desktopRepository.removeBoundsBeforeFullImmersive(pendingExit.taskId)
-                    }
-                }
-            }
-            return
-        }
+        val pendingTransition = getImmersiveTransition(transition)
 
-        // Check if this is a direct immersive enter/exit transition.
-        if (transition == state?.transition) {
-            val state = requireState()
-            val immersiveChange =
-                info.changes.firstOrNull { c -> c.taskInfo?.taskId == state.taskId }
+        if (pendingTransition != null) {
+            val taskId = pendingTransition.taskId
+            val immersiveChange = info.getTaskChange(taskId = taskId)
             if (immersiveChange == null) {
                 logV(
-                    "Direct move for task#%d in %s direction missing immersive change.",
-                    state.taskId,
-                    state.direction,
+                    "Transition for task#%d in %s direction missing immersive change.",
+                    taskId,
+                    pendingTransition.direction,
                 )
                 return
             }
-            val startBounds = immersiveChange.startAbsBounds
-            logV("Direct move for task#%d in %s direction verified", state.taskId, state.direction)
-
-            when (state.direction) {
-                Direction.ENTER -> {
-                    desktopRepository.setTaskInFullImmersiveState(
-                        displayId = state.displayId,
-                        taskId = state.taskId,
-                        immersive = true,
-                    )
-                    if (Flags.enableRestoreToPreviousSizeFromDesktopImmersive()) {
-                        desktopRepository.saveBoundsBeforeFullImmersive(state.taskId, startBounds)
+            logV(
+                "Immersive transition for task#%d in %s direction verified",
+                taskId,
+                pendingTransition.direction,
+            )
+            desktopRepository.setTaskInFullImmersiveState(
+                displayId = pendingTransition.displayId,
+                taskId = taskId,
+                immersive = pendingTransition.direction == Direction.ENTER,
+            )
+            if (Flags.enableRestoreToPreviousSizeFromDesktopImmersive()) {
+                when (pendingTransition.direction) {
+                    Direction.EXIT -> {
+                        desktopRepository.removeBoundsBeforeFullImmersive(taskId)
                     }
-                }
-                Direction.EXIT -> {
-                    desktopRepository.setTaskInFullImmersiveState(
-                        displayId = state.displayId,
-                        taskId = state.taskId,
-                        immersive = false,
-                    )
-                    if (Flags.enableRestoreToPreviousSizeFromDesktopImmersive()) {
-                        desktopRepository.removeBoundsBeforeFullImmersive(state.taskId)
+                    Direction.ENTER -> {
+                        desktopRepository.saveBoundsBeforeFullImmersive(
+                            taskId,
+                            immersiveChange.startAbsBounds,
+                        )
                     }
                 }
             }
-            return
         }
 
         // Check if this is an untracked exit transition, like display rotation.
@@ -450,35 +427,31 @@
     }
 
     override fun onTransitionMerged(merged: IBinder, playing: IBinder) {
-        val pendingExit =
-            pendingExternalExitTransitions.firstOrNull { pendingExit ->
-                pendingExit.transition == merged
+        val pendingTransition =
+            pendingImmersiveTransitions.firstOrNull { pendingTransition ->
+                pendingTransition.transition == merged
             }
-        if (pendingExit != null) {
+        if (pendingTransition != null) {
             logV(
-                "Pending exit transition %s for task#%s merged into %s",
+                "Pending transition %s for task#%s merged into %s",
                 merged,
-                pendingExit.taskId,
+                pendingTransition.taskId,
                 playing,
             )
-            pendingExit.transition = playing
+            pendingTransition.transition = playing
         }
     }
 
     override fun onTransitionFinished(transition: IBinder, aborted: Boolean) {
-        val pendingExit =
-            pendingExternalExitTransitions.firstOrNull { pendingExit ->
-                pendingExit.transition == transition
-            }
-        if (pendingExit != null) {
-            logV("Pending exit transition %s for task#%s finished", transition, pendingExit)
-            pendingExternalExitTransitions.remove(pendingExit)
+        val pendingTransition = getImmersiveTransition(transition)
+        if (pendingTransition != null) {
+            logV("Pending exit transition %s for task#%s finished", transition, pendingTransition)
+            pendingImmersiveTransitions.remove(pendingTransition)
         }
     }
 
-    private fun clearState() {
-        state = null
-    }
+    private fun getImmersiveTransition(transition: IBinder) =
+        pendingImmersiveTransitions.firstOrNull { it.transition == transition }
 
     private fun getExitDestinationBounds(taskInfo: RunningTaskInfo): Rect {
         val displayLayout =
@@ -496,24 +469,13 @@
         }
     }
 
-    private fun requireState(): TransitionState =
-        state ?: error("Expected non-null transition state")
-
-    private fun getRunningTransitions(): List<IBinder> {
-        val running = mutableListOf<IBinder>()
-        state?.let { running.add(it.transition) }
-        pendingExternalExitTransitions.forEach { running.add(it.transition) }
-        return running
-    }
-
-    private fun TransitionInfo.hasTaskChange(taskId: Int): Boolean =
-        changes.any { c -> c.taskInfo?.taskId == taskId }
+    private fun TransitionInfo.getTaskChange(taskId: Int): TransitionInfo.Change? =
+        changes.firstOrNull { c -> c.taskInfo?.taskId == taskId }
 
     private fun dump(pw: PrintWriter, prefix: String) {
         val innerPrefix = "$prefix  "
         pw.println("${prefix}DesktopImmersiveController")
-        pw.println(innerPrefix + "state=" + state)
-        pw.println(innerPrefix + "pendingExternalExitTransitions=" + pendingExternalExitTransitions)
+        pw.println(innerPrefix + "pendingImmersiveTransitions=" + pendingImmersiveTransitions)
     }
 
     /** The state of the currently running transition. */
@@ -526,12 +488,22 @@
     )
 
     /**
-     * Tracks state of a transition involving an immersive exit that is external to this class' own
-     * transitions. This usually means transitions that exit immersive mode as a side-effect and not
-     * the primary action (for example, minimizing the immersive task or launching a new task on top
-     * of the immersive task).
+     * Tracks state of a transition involving an immersive enter or exit. This includes both
+     * transitions that should and should not be animated by this handler.
+     *
+     * @param taskId of the task that should enter/exit immersive mode
+     * @param displayId of the display that should enter/exit immersive mode
+     * @param direction of the immersive transition
+     * @param transition that will apply this transaction
+     * @param animate whether transition should be animated by this handler
      */
-    data class ExternalPendingExit(val taskId: Int, val displayId: Int, var transition: IBinder)
+    data class PendingTransition(
+        val taskId: Int,
+        val displayId: Int,
+        val direction: Direction,
+        var transition: IBinder,
+        val animate: Boolean,
+    )
 
     /** The result of an external exit request. */
     sealed class ExitResult {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
index 14623cf..606a729 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
@@ -235,8 +235,7 @@
 
 /** Returns true if task bound is equal to stable bounds else returns false. */
 fun isTaskBoundsEqual(taskBounds: Rect, stableBounds: Rect): Boolean {
-    return taskBounds.width() == stableBounds.width() &&
-        taskBounds.height() == stableBounds.height()
+    return taskBounds == stableBounds
 }
 
 /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
index bccb609..c4abee3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
@@ -220,11 +220,18 @@
     fun isMinimizedTask(taskId: Int) = desktopTaskDataSequence().any { taskId in it.minimizedTasks }
 
     /** Checks if a task is the only visible, non-closing, non-minimized task on its display. */
-    fun isOnlyVisibleNonClosingTask(taskId: Int): Boolean =
-        desktopTaskDataSequence().any {
+    fun isOnlyVisibleNonClosingTask(taskId: Int, displayId: Int = INVALID_DISPLAY): Boolean {
+        val seq =
+            if (displayId != INVALID_DISPLAY) {
+                sequenceOf(desktopTaskDataByDisplayId[displayId]).filterNotNull()
+            } else {
+                desktopTaskDataSequence()
+            }
+        return seq.any {
             it.visibleTasks.subtract(it.closingTasks).subtract(it.minimizedTasks).singleOrNull() ==
                 taskId
         }
+    }
 
     fun getActiveTasks(displayId: Int): ArraySet<Int> =
         ArraySet(desktopTaskDataByDisplayId[displayId]?.activeTasks)
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 1a48404..9b7c3a4 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
@@ -363,8 +363,15 @@
         }
 
         val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(displayId)
-        requireNotNull(tdaInfo) {
-            "This method can only be called with the ID of a display having non-null DisplayArea."
+        // A non-organized display (e.g., non-trusted virtual displays used in CTS) doesn't have
+        // TDA.
+        if (tdaInfo == null) {
+            logW(
+                "forceEnterDesktop cannot find DisplayAreaInfo for displayId=%d. This could happen" +
+                    " when the display is a non-trusted virtual display.",
+                displayId,
+            )
+            return false
         }
         val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode
         val isFreeformDisplay = tdaWindowingMode == WINDOWING_MODE_FREEFORM
@@ -376,12 +383,13 @@
         taskId: Int,
         wct: WindowContainerTransaction = WindowContainerTransaction(),
         transitionSource: DesktopModeTransitionSource,
+        remoteTransition: RemoteTransition? = null,
     ): Boolean {
         val runningTask = shellTaskOrganizer.getRunningTaskInfo(taskId)
         if (runningTask == null) {
-            return moveBackgroundTaskToDesktop(taskId, wct, transitionSource)
+            return moveBackgroundTaskToDesktop(taskId, wct, transitionSource, remoteTransition)
         }
-        moveRunningTaskToDesktop(runningTask, wct, transitionSource)
+        moveRunningTaskToDesktop(runningTask, wct, transitionSource, remoteTransition)
         return true
     }
 
@@ -389,6 +397,7 @@
         taskId: Int,
         wct: WindowContainerTransaction,
         transitionSource: DesktopModeTransitionSource,
+        remoteTransition: RemoteTransition? = null,
     ): Boolean {
         if (recentTasksController?.findTaskInBackground(taskId) == null) {
             logW("moveBackgroundTaskToDesktop taskId=%d not found", taskId)
@@ -411,8 +420,17 @@
                 .apply { launchWindowingMode = WINDOWING_MODE_FREEFORM }
                 .toBundle(),
         )
-        // TODO(343149901): Add DPI changes for task launch
-        val transition = enterDesktopTaskTransitionHandler.moveToDesktop(wct, transitionSource)
+
+        val transition: IBinder
+        if (remoteTransition != null) {
+            val transitionType = transitionType(remoteTransition)
+            val remoteTransitionHandler = OneShotRemoteHandler(mainExecutor, remoteTransition)
+            transition = transitions.startTransition(transitionType, wct, remoteTransitionHandler)
+            remoteTransitionHandler.setTransition(transition)
+        } else {
+            // TODO(343149901): Add DPI changes for task launch
+            transition = enterDesktopTaskTransitionHandler.moveToDesktop(wct, transitionSource)
+        }
         desktopModeEnterExitTransitionListener?.onEnterDesktopModeTransitionStarted(
             FREEFORM_ANIMATION_DURATION
         )
@@ -426,6 +444,7 @@
         task: RunningTaskInfo,
         wct: WindowContainerTransaction = WindowContainerTransaction(),
         transitionSource: DesktopModeTransitionSource,
+        remoteTransition: RemoteTransition? = null,
     ) {
         if (
             DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODALS_POLICY.isTrue() &&
@@ -443,12 +462,21 @@
                 excludeTaskId = task.taskId,
                 reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
             )
+
         // Bring other apps to front first
         val taskIdToMinimize =
             bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId)
         addMoveToDesktopChanges(wct, task)
 
-        val transition = enterDesktopTaskTransitionHandler.moveToDesktop(wct, transitionSource)
+        val transition: IBinder
+        if (remoteTransition != null) {
+            val transitionType = transitionType(remoteTransition)
+            val remoteTransitionHandler = OneShotRemoteHandler(mainExecutor, remoteTransition)
+            transition = transitions.startTransition(transitionType, wct, remoteTransitionHandler)
+            remoteTransitionHandler.setTransition(transition)
+        } else {
+            transition = enterDesktopTaskTransitionHandler.moveToDesktop(wct, transitionSource)
+        }
         desktopModeEnterExitTransitionListener?.onEnterDesktopModeTransitionStarted(
             FREEFORM_ANIMATION_DURATION
         )
@@ -543,7 +571,7 @@
     ): ((IBinder) -> Unit)? {
         val taskId = taskInfo.taskId
         desktopTilingDecorViewModel.removeTaskIfTiled(displayId, taskId)
-        performDesktopExitCleanupIfNeeded(taskId, wct)
+        performDesktopExitCleanupIfNeeded(taskId, displayId, wct)
         taskRepository.addClosingTask(displayId, taskId)
         taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(
             doesAnyTaskRequireTaskbarRounding(displayId, taskId)
@@ -582,7 +610,7 @@
         val taskId = taskInfo.taskId
         val displayId = taskInfo.displayId
         val wct = WindowContainerTransaction()
-        performDesktopExitCleanupIfNeeded(taskId, wct)
+        performDesktopExitCleanupIfNeeded(taskId, displayId, wct)
         // Notify immersive handler as it might need to exit immersive state.
         val exitResult =
             desktopImmersiveController.exitImmersiveIfApplicable(
@@ -836,6 +864,10 @@
         if (!task.isFreeform) addMoveToDesktopChanges(wct, task, displayId)
         wct.reparent(task.token, displayAreaInfo.token, true /* onTop */)
 
+        if (Flags.enablePerDisplayDesktopWallpaperActivity()) {
+            performDesktopExitCleanupIfNeeded(task.taskId, task.displayId, wct)
+        }
+
         transitions.startTransition(TRANSIT_CHANGE, wct, null /* handler */)
     }
 
@@ -906,7 +938,10 @@
             destinationBounds.height(),
             displayController,
         )
-        toggleResizeDesktopTaskTransitionHandler.startTransition(wct)
+        toggleResizeDesktopTaskTransitionHandler.startTransition(
+            wct,
+            interaction.animationStartBounds,
+        )
     }
 
     private fun dragToMaximizeDesktopTask(
@@ -937,6 +972,7 @@
                 direction = ToggleTaskSizeInteraction.Direction.MAXIMIZE,
                 source = ToggleTaskSizeInteraction.Source.HEADER_DRAG_TO_TOP,
                 inputMethod = DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent),
+                animationStartBounds = currentDragBounds,
             ),
         )
     }
@@ -1316,9 +1352,22 @@
      * Remove wallpaper activity if task provided is last task and wallpaper activity token is not
      * null
      */
-    private fun performDesktopExitCleanupIfNeeded(taskId: Int, wct: WindowContainerTransaction) {
-        if (!taskRepository.isOnlyVisibleNonClosingTask(taskId)) {
-            return
+    private fun performDesktopExitCleanupIfNeeded(
+        taskId: Int,
+        displayId: Int,
+        wct: WindowContainerTransaction,
+    ) {
+        if (Flags.enablePerDisplayDesktopWallpaperActivity()) {
+            if (!taskRepository.isOnlyVisibleNonClosingTask(taskId, displayId)) {
+                return
+            }
+            if (displayId != DEFAULT_DISPLAY) {
+                return
+            }
+        } else {
+            if (!taskRepository.isOnlyVisibleNonClosingTask(taskId)) {
+                return
+            }
         }
         desktopModeEnterExitTransitionListener?.onExitDesktopModeTransitionStarted(
             FULLSCREEN_ANIMATION_DURATION
@@ -1812,7 +1861,7 @@
         if (!isDesktopModeShowing(task.displayId)) return null
 
         val wct = WindowContainerTransaction()
-        performDesktopExitCleanupIfNeeded(task.taskId, wct)
+        performDesktopExitCleanupIfNeeded(task.taskId, task.displayId, wct)
 
         if (!DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION.isTrue()) {
             taskRepository.addClosingTask(task.displayId, task.taskId)
@@ -1895,7 +1944,7 @@
             wct.setDensityDpi(taskInfo.token, getDefaultDensityDpi())
         }
 
-        performDesktopExitCleanupIfNeeded(taskInfo.taskId, wct)
+        performDesktopExitCleanupIfNeeded(taskInfo.taskId, taskInfo.displayId, wct)
     }
 
     private fun cascadeWindow(bounds: Rect, displayLayout: DisplayLayout, displayId: Int) {
@@ -1929,7 +1978,7 @@
         // want it overridden in multi-window.
         wct.setDensityDpi(taskInfo.token, getDefaultDensityDpi())
 
-        performDesktopExitCleanupIfNeeded(taskInfo.taskId, wct)
+        performDesktopExitCleanupIfNeeded(taskInfo.taskId, taskInfo.displayId, wct)
     }
 
     /** Returns the ID of the Task that will be minimized, or null if no task will be minimized. */
@@ -2646,9 +2695,17 @@
             }
         }
 
-        override fun moveToDesktop(taskId: Int, transitionSource: DesktopModeTransitionSource) {
+        override fun moveToDesktop(
+            taskId: Int,
+            transitionSource: DesktopModeTransitionSource,
+            remoteTransition: RemoteTransition?,
+        ) {
             executeRemoteCallWithTaskPermission(controller, "moveTaskToDesktop") { c ->
-                c.moveTaskToDesktop(taskId, transitionSource = transitionSource)
+                c.moveTaskToDesktop(
+                    taskId,
+                    transitionSource = transitionSource,
+                    remoteTransition = remoteTransition,
+                )
             }
         }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt
index e5f5283..8b5d1c5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt
@@ -28,6 +28,7 @@
 import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
 import com.android.wm.shell.shared.annotations.ShellMainThread
 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
+import com.android.wm.shell.sysui.ShellController
 import com.android.wm.shell.sysui.ShellInit
 import com.android.wm.shell.sysui.UserChangeListener
 import kotlinx.coroutines.CoroutineScope
@@ -36,6 +37,7 @@
 class DesktopUserRepositories(
     context: Context,
     shellInit: ShellInit,
+    private val shellController: ShellController,
     private val persistentRepository: DesktopPersistentRepository,
     private val repositoryInitializer: DesktopRepositoryInitializer,
     @ShellMainThread private val mainCoroutineScope: CoroutineScope,
@@ -61,15 +63,16 @@
     init {
         userId = ActivityManager.getCurrentUser()
         if (DesktopModeStatus.canEnterDesktopMode(context)) {
-            shellInit.addInitCallback(::initRepoFromPersistentStorage, this)
+            shellInit.addInitCallback(::onInit, this)
         }
         if (Flags.enableDesktopWindowingHsum()) {
             userIdToProfileIdsMap[userId] = userManager.getProfiles(userId).map { it.id }
         }
     }
 
-    private fun initRepoFromPersistentStorage() {
+    private fun onInit() {
         repositoryInitializer.initialize(this)
+        shellController.addUserChangeListener(this)
     }
 
     /** Returns [DesktopRepository] for the parent user id. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
index aac2361..fa383cb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
@@ -53,7 +53,8 @@
     oneway void setTaskListener(IDesktopTaskListener listener);
 
     /** Move a task with given `taskId` to desktop */
-    void moveToDesktop(int taskId, in DesktopModeTransitionSource transitionSource);
+    void moveToDesktop(int taskId, in DesktopModeTransitionSource transitionSource,
+                        in @nullable RemoteTransition remoteTransition);
 
     /** Remove desktop on the given display */
     oneway void removeDesktop(int displayId);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/ToggleTaskSizeUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/ToggleTaskSizeUtils.kt
index 7afd8d7..f6ebf72 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/ToggleTaskSizeUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/ToggleTaskSizeUtils.kt
@@ -15,6 +15,7 @@
  */
 package com.android.wm.shell.desktopmode.common
 
+import android.graphics.Rect
 import com.android.internal.jank.Cuj
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
@@ -23,10 +24,13 @@
 import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction.Source
 
 /** Represents a user interaction to toggle a desktop task's size from to maximize or vice versa. */
-data class ToggleTaskSizeInteraction(
+data class ToggleTaskSizeInteraction
+@JvmOverloads
+constructor(
     val direction: Direction,
     val source: Source,
     val inputMethod: InputMethod,
+    val animationStartBounds: Rect? = null,
 ) {
     constructor(
         isMaximized: Boolean,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
index c5fca02..45d1281 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
@@ -23,7 +23,6 @@
 import android.graphics.Point
 import android.os.SystemProperties
 import android.util.Slog
-import androidx.core.content.withStyledAttributes
 import com.android.window.flags.Flags
 import com.android.wm.shell.R
 import com.android.wm.shell.desktopmode.CaptionState
@@ -299,31 +298,12 @@
     }
 
     private fun tooltipColorScheme(captionState: CaptionState): TooltipColorScheme {
-        context.withStyledAttributes(
-            set = null,
-            attrs =
-                intArrayOf(
-                    com.android.internal.R.attr.materialColorOnTertiaryFixed,
-                    com.android.internal.R.attr.materialColorTertiaryFixed,
-                    com.android.internal.R.attr.materialColorTertiaryFixedDim,
-                ),
-            defStyleAttr = 0,
-            defStyleRes = 0,
-        ) {
-            val onTertiaryFixed = getColor(/* index= */ 0, /* defValue= */ 0)
-            val tertiaryFixed = getColor(/* index= */ 1, /* defValue= */ 0)
-            val tertiaryFixedDim = getColor(/* index= */ 2, /* defValue= */ 0)
-            val taskInfo = (captionState as CaptionState.AppHandle).runningTaskInfo
+        val onTertiaryFixed =
+            context.getColor(com.android.internal.R.color.materialColorOnTertiaryFixed)
+        val tertiaryFixed =
+            context.getColor(com.android.internal.R.color.materialColorTertiaryFixed)
 
-            val tooltipContainerColor =
-                if (decorThemeUtil.getAppTheme(taskInfo) == Theme.LIGHT) {
-                    tertiaryFixed
-                } else {
-                    tertiaryFixedDim
-                }
-            return TooltipColorScheme(tooltipContainerColor, onTertiaryFixed, onTertiaryFixed)
-        }
-        return TooltipColorScheme(0, 0, 0)
+        return TooltipColorScheme(tertiaryFixed, onTertiaryFixed, onTertiaryFixed)
     }
 
     /**
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 dae3c21..acb5622b 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
@@ -124,7 +124,6 @@
     // Internal state and relevant cached info
     //
 
-    @Nullable
     private Transitions.TransitionFinishCallback mFinishCallback;
 
     private ValueAnimator mTransitionAnimator;
@@ -236,7 +235,6 @@
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback) {
-        mFinishCallback = finishCallback;
         if (transition == mEnterTransition || info.getType() == TRANSIT_PIP) {
             mEnterTransition = null;
             // If we are in swipe PiP to Home transition we are ENTERING_PIP as a jumpcut transition
@@ -282,7 +280,6 @@
         if (isRemovePipTransition(info)) {
             return removePipImmediately(info, startTransaction, finishTransaction, finishCallback);
         }
-        mFinishCallback = null;
         return false;
     }
 
@@ -331,6 +328,7 @@
         if (pipChange == null) {
             return false;
         }
+        mFinishCallback = finishCallback;
         // We expect the PiP activity as a separate change in a config-at-end transition;
         // only flings are not using config-at-end for resize bounds changes
         TransitionInfo.Change pipActivityChange = getDeferConfigActivityChange(info,
@@ -378,6 +376,7 @@
         if (pipActivityChange == null) {
             return false;
         }
+        mFinishCallback = finishCallback;
 
         final SurfaceControl pipLeash = getLeash(pipChange);
         final Rect destinationBounds = pipChange.getEndAbsBounds();
@@ -446,6 +445,7 @@
         if (pipActivityChange == null) {
             return false;
         }
+        mFinishCallback = finishCallback;
 
         final SurfaceControl pipLeash = getLeash(pipChange);
         final Rect startBounds = pipChange.getStartAbsBounds();
@@ -572,6 +572,7 @@
         if (pipChange == null) {
             return false;
         }
+        mFinishCallback = finishCallback;
 
         Rect destinationBounds = pipChange.getEndAbsBounds();
         SurfaceControl pipLeash = mPipTransitionState.getPinnedTaskLeash();
@@ -614,6 +615,7 @@
                 return false;
             }
         }
+        mFinishCallback = finishCallback;
 
         // The parent change if we were in a multi-activity PiP; null if single activity PiP.
         final TransitionInfo.Change parentBeforePip = pipChange.getTaskInfo() == null
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 a368245..5dd49f0 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
@@ -185,6 +185,7 @@
     private final LauncherApps mLauncherApps;
     private final RootTaskDisplayAreaOrganizer mRootTDAOrganizer;
     private final ShellExecutor mMainExecutor;
+    private final ShellExecutor mBgExecutor;
     private final Handler mMainHandler;
     private final SplitScreenImpl mImpl = new SplitScreenImpl();
     private final DisplayController mDisplayController;
@@ -231,7 +232,8 @@
             MultiInstanceHelper multiInstanceHelper,
             SplitState splitState,
             ShellExecutor mainExecutor,
-            Handler mainHandler) {
+            Handler mainHandler,
+            ShellExecutor bgExecutor) {
         mShellCommandHandler = shellCommandHandler;
         mShellController = shellController;
         mTaskOrganizer = shellTaskOrganizer;
@@ -241,6 +243,7 @@
         mRootTDAOrganizer = rootTDAOrganizer;
         mMainExecutor = mainExecutor;
         mMainHandler = mainHandler;
+        mBgExecutor = bgExecutor;
         mDisplayController = displayController;
         mDisplayImeController = displayImeController;
         mDisplayInsetsController = displayInsetsController;
@@ -298,8 +301,8 @@
         return new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
                 mTaskOrganizer, mDisplayController, mDisplayImeController,
                 mDisplayInsetsController, mTransitions, mTransactionPool, mIconProvider,
-                mMainExecutor, mMainHandler, mRecentTasksOptional, mLaunchAdjacentController,
-                mWindowDecorViewModel, mSplitState);
+                mMainExecutor, mMainHandler, mBgExecutor, mRecentTasksOptional,
+                mLaunchAdjacentController, mWindowDecorViewModel, mSplitState);
     }
 
     @Override
@@ -512,6 +515,11 @@
         mStageCoordinator.getStageBounds(outTopOrLeftBounds, outBottomOrRightBounds);
     }
 
+    /** Get the parent-based coordinates for split stages. */
+    public void getRefStageBounds(Rect outTopOrLeftBounds, Rect outBottomOrRightBounds) {
+        mStageCoordinator.getRefStageBounds(outTopOrLeftBounds, outBottomOrRightBounds);
+    }
+
     public void registerSplitScreenListener(SplitScreen.SplitScreenListener listener) {
         mStageCoordinator.registerSplitScreenListener(listener);
     }
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 b40996f..e48c887 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
@@ -213,6 +213,7 @@
     private final SplitscreenEventLogger mLogger;
     private final ShellExecutor mMainExecutor;
     private final Handler mMainHandler;
+    private final ShellExecutor mBgExecutor;
     // Cache live tile tasks while entering recents, evict them from stages in finish transaction
     // if user is opening another task(s).
     private final ArrayList<Integer> mPausingTasks = new ArrayList<>();
@@ -340,12 +341,20 @@
                 }
             };
 
-    protected StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
-            ShellTaskOrganizer taskOrganizer, DisplayController displayController,
+    protected StageCoordinator(Context context,
+            int displayId,
+            SyncTransactionQueue syncQueue,
+            ShellTaskOrganizer taskOrganizer,
+            DisplayController displayController,
             DisplayImeController displayImeController,
-            DisplayInsetsController displayInsetsController, Transitions transitions,
-            TransactionPool transactionPool, IconProvider iconProvider, ShellExecutor mainExecutor,
-            Handler mainHandler, Optional<RecentTasksController> recentTasks,
+            DisplayInsetsController displayInsetsController,
+            Transitions transitions,
+            TransactionPool transactionPool,
+            IconProvider iconProvider,
+            ShellExecutor mainExecutor,
+            Handler mainHandler,
+            ShellExecutor bgExecutor,
+            Optional<RecentTasksController> recentTasks,
             LaunchAdjacentController launchAdjacentController,
             Optional<WindowDecorViewModel> windowDecorViewModel, SplitState splitState) {
         mContext = context;
@@ -355,6 +364,7 @@
         mLogger = new SplitscreenEventLogger();
         mMainExecutor = mainExecutor;
         mMainHandler = mainHandler;
+        mBgExecutor = bgExecutor;
         mRecentTasks = recentTasks;
         mLaunchAdjacentController = launchAdjacentController;
         mWindowDecorViewModel = windowDecorViewModel;
@@ -370,6 +380,8 @@
                     this /*stageListenerCallbacks*/,
                     mSyncQueue,
                     iconProvider,
+                    mMainExecutor,
+                    mBgExecutor,
                     mWindowDecorViewModel);
         } else {
             mMainStage = new StageTaskListener(
@@ -379,6 +391,8 @@
                     this /*stageListenerCallbacks*/,
                     mSyncQueue,
                     iconProvider,
+                    mMainExecutor,
+                    mBgExecutor,
                     mWindowDecorViewModel, STAGE_TYPE_MAIN);
             mSideStage = new StageTaskListener(
                     mContext,
@@ -387,6 +401,8 @@
                     this /*stageListenerCallbacks*/,
                     mSyncQueue,
                     iconProvider,
+                    mMainExecutor,
+                    mBgExecutor,
                     mWindowDecorViewModel, STAGE_TYPE_SIDE);
         }
         mDisplayController = displayController;
@@ -408,13 +424,22 @@
     }
 
     @VisibleForTesting
-    StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
-            ShellTaskOrganizer taskOrganizer, StageTaskListener mainStage,
-            StageTaskListener sideStage, DisplayController displayController,
+    StageCoordinator(Context context,
+            int displayId,
+            SyncTransactionQueue syncQueue,
+            ShellTaskOrganizer taskOrganizer,
+            StageTaskListener mainStage,
+            StageTaskListener sideStage,
+            DisplayController displayController,
             DisplayImeController displayImeController,
-            DisplayInsetsController displayInsetsController, SplitLayout splitLayout,
-            Transitions transitions, TransactionPool transactionPool, ShellExecutor mainExecutor,
-            Handler mainHandler, Optional<RecentTasksController> recentTasks,
+            DisplayInsetsController displayInsetsController,
+            SplitLayout splitLayout,
+            Transitions transitions,
+            TransactionPool transactionPool,
+            ShellExecutor mainExecutor,
+            Handler mainHandler,
+            ShellExecutor bgExecutor,
+            Optional<RecentTasksController> recentTasks,
             LaunchAdjacentController launchAdjacentController,
             Optional<WindowDecorViewModel> windowDecorViewModel, SplitState splitState) {
         mContext = context;
@@ -433,6 +458,7 @@
         mLogger = new SplitscreenEventLogger();
         mMainExecutor = mainExecutor;
         mMainHandler = mainHandler;
+        mBgExecutor = bgExecutor;
         mRecentTasks = recentTasks;
         mLaunchAdjacentController = launchAdjacentController;
         mWindowDecorViewModel = windowDecorViewModel;
@@ -1776,6 +1802,11 @@
         outBottomOrRightBounds.set(mSplitLayout.getBottomRightBounds());
     }
 
+    void getRefStageBounds(Rect outTopOrLeftBounds, Rect outBottomOrRightBounds) {
+        outTopOrLeftBounds.set(mSplitLayout.getTopLeftRefBounds());
+        outBottomOrRightBounds.set(mSplitLayout.getBottomRightRefBounds());
+    }
+
     private void runForActiveStages(Consumer<StageTaskListener> consumer) {
         mStageOrderOperator.getActiveStages().forEach(consumer);
     }
@@ -1964,32 +1995,32 @@
                 }
             }
 
-            int currentSnapPosition = mSplitLayout.calculateCurrentSnapPosition();
-
-            if (Flags.enableFlexibleTwoAppSplit()) {
-                // Split screen can be laid out in such a way that some of the apps are offscreen.
-                // For the purposes of passing SplitBounds up to launcher (for use in thumbnails
-                // etc.), we crop the bounds down to the screen size.
-                topLeftBounds.left =
-                        Math.max(topLeftBounds.left, 0);
-                topLeftBounds.top =
-                        Math.max(topLeftBounds.top, 0);
-                bottomRightBounds.right =
-                        Math.min(bottomRightBounds.right, mSplitLayout.getDisplayWidth());
-                bottomRightBounds.top =
-                        Math.min(bottomRightBounds.top, mSplitLayout.getDisplayHeight());
-
-                // TODO (b/349828130): Can change to getState() fully after brief soak time.
-                if (mSplitState.get() != currentSnapPosition) {
-                    Log.wtf(TAG, "SplitState is " + mSplitState.get()
-                            + ", expected " + currentSnapPosition);
-                    currentSnapPosition = mSplitState.get();
-                }
-            }
-
-            SplitBounds splitBounds = new SplitBounds(topLeftBounds, bottomRightBounds,
-                    leftTopTaskId, rightBottomTaskId, currentSnapPosition);
+            // If all stages are filled, create new SplitBounds and update Recents.
             if (mainStageTopTaskId != INVALID_TASK_ID && sideStageTopTaskId != INVALID_TASK_ID) {
+                int currentSnapPosition = mSplitLayout.calculateCurrentSnapPosition();
+                if (Flags.enableFlexibleTwoAppSplit()) {
+                    // Split screen can be laid out in such a way that some of the apps are
+                    // offscreen. For the purposes of passing SplitBounds up to launcher (for use in
+                    // thumbnails etc.), we crop the bounds down to the screen size.
+                    topLeftBounds.left =
+                            Math.max(topLeftBounds.left, 0);
+                    topLeftBounds.top =
+                            Math.max(topLeftBounds.top, 0);
+                    bottomRightBounds.right =
+                            Math.min(bottomRightBounds.right, mSplitLayout.getDisplayWidth());
+                    bottomRightBounds.top =
+                            Math.min(bottomRightBounds.top, mSplitLayout.getDisplayHeight());
+
+                    // TODO (b/349828130): Can change to getState() fully after brief soak time.
+                    if (mSplitState.get() != currentSnapPosition) {
+                        Log.wtf(TAG, "SplitState is " + mSplitState.get()
+                                + ", expected " + currentSnapPosition);
+                        currentSnapPosition = mSplitState.get();
+                    }
+                }
+                SplitBounds splitBounds = new SplitBounds(topLeftBounds, bottomRightBounds,
+                        leftTopTaskId, rightBottomTaskId, currentSnapPosition);
+
                 // Update the pair for the top tasks
                 boolean added = recentTasks.addSplitPair(mainStageTopTaskId, sideStageTopTaskId,
                         splitBounds);
@@ -2150,8 +2181,7 @@
         wct.setForceTranslucent(mRootTaskInfo.token, translucent);
     }
 
-    /** Callback when split roots visiblility changed.
-     * NOTICE: This only be called on legacy transition. */
+    /** Callback when split roots visiblility changed. */
     @Override
     public void onStageVisibilityChanged(StageTaskListener stageListener) {
         // If split didn't active, just ignore this callback because we should already did these
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageOrderOperator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageOrderOperator.kt
index 3fa8df4..5256e78 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageOrderOperator.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageOrderOperator.kt
@@ -20,6 +20,7 @@
 import com.android.internal.protolog.ProtoLog
 import com.android.launcher3.icons.IconProvider
 import com.android.wm.shell.ShellTaskOrganizer
+import com.android.wm.shell.common.ShellExecutor
 import com.android.wm.shell.common.SyncTransactionQueue
 import com.android.wm.shell.protolog.ShellProtoLogGroup
 import com.android.wm.shell.shared.split.SplitScreenConstants
@@ -52,6 +53,8 @@
         stageCallbacks: StageTaskListener.StageListenerCallbacks,
         syncQueue: SyncTransactionQueue,
         iconProvider: IconProvider,
+        mainExecutor: ShellExecutor,
+        bgExecutor: ShellExecutor,
         windowDecorViewModel: Optional<WindowDecorViewModel>
     ) {
 
@@ -83,6 +86,8 @@
                 stageCallbacks,
                 syncQueue,
                 iconProvider,
+                mainExecutor,
+                bgExecutor,
                 windowDecorViewModel,
                 stageIds[i])
             )
@@ -95,13 +100,16 @@
      */
     fun onEnteringSplit(@SnapPosition goingToLayout: Int) {
         if (goingToLayout == currentLayout) {
-            // Add protolog here. Return for now, but maybe we want to handle swap case, TBD
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
+                "Entering Split requested same layout split is in: %d", goingToLayout)
             return
         }
         val freeStages: List<StageTaskListener> =
             allStages.filterNot { activeStages.contains(it) }
         when(goingToLayout) {
-            SplitScreenConstants.SNAP_TO_2_50_50 -> {
+            SplitScreenConstants.SNAP_TO_2_50_50,
+            SplitScreenConstants.SNAP_TO_2_33_66,
+            SplitScreenConstants.SNAP_TO_2_66_33 -> {
                 if (activeStages.size < 2) {
                     // take from allStages and add into activeStages
                     for (i in 0 until (2 - activeStages.size)) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index 4a37169..816f51f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -48,6 +48,7 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SurfaceUtils;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.common.split.SplitDecorManager;
@@ -95,6 +96,8 @@
     private final StageListenerCallbacks mCallbacks;
     private final SyncTransactionQueue mSyncQueue;
     private final IconProvider mIconProvider;
+    private final ShellExecutor mMainExecutor;
+    private final ShellExecutor mBgExecutor;
     private final Optional<WindowDecorViewModel> mWindowDecorViewModel;
 
     /** Whether or not the root task has been created. */
@@ -111,14 +114,21 @@
     // TODO(b/204308910): Extracts SplitDecorManager related code to common package.
     private SplitDecorManager mSplitDecorManager;
 
-    StageTaskListener(Context context, ShellTaskOrganizer taskOrganizer, int displayId,
-            StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
+    StageTaskListener(Context context,
+            ShellTaskOrganizer taskOrganizer,
+            int displayId,
+            StageListenerCallbacks callbacks,
+            SyncTransactionQueue syncQueue,
             IconProvider iconProvider,
+            ShellExecutor mainExecutor,
+            ShellExecutor bgExecutor,
             Optional<WindowDecorViewModel> windowDecorViewModel, int id) {
         mContext = context;
         mCallbacks = callbacks;
         mSyncQueue = syncQueue;
         mIconProvider = iconProvider;
+        mMainExecutor = mainExecutor;
+        mBgExecutor = bgExecutor;
         mWindowDecorViewModel = windowDecorViewModel;
         taskOrganizer.createRootTask(displayId, WINDOWING_MODE_MULTI_WINDOW, this);
         mId = id;
@@ -214,9 +224,8 @@
         if (mRootTaskInfo == null) {
             mRootLeash = leash;
             mRootTaskInfo = taskInfo;
-            mSplitDecorManager = new SplitDecorManager(
-                    mRootTaskInfo.configuration,
-                    mIconProvider);
+            mSplitDecorManager = new SplitDecorManager(mRootTaskInfo.configuration, mIconProvider,
+                    mMainExecutor, mBgExecutor);
             mHasRootTask = true;
             mCallbacks.onRootTaskAppeared();
             if (mVisible != mRootTaskInfo.isVisible) {
@@ -240,12 +249,20 @@
     @Override
     @CallSuper
     public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
-        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTaskInfoChanged: taskId=%d taskAct=%s "
-                        + "stageId=%s",
-                taskInfo.taskId, taskInfo.baseActivity, stageTypeToString(mId));
+        ProtoLog.d(WM_SHELL_SPLIT_SCREEN,
+                "onTaskInfoChanged: taskId=%d vis=%b reqVis=%b baseAct=%s stageId=%s",
+                taskInfo.taskId, taskInfo.isVisible, taskInfo.isVisibleRequested,
+                taskInfo.baseActivity, stageTypeToString(mId));
         mWindowDecorViewModel.ifPresent(viewModel -> viewModel.onTaskInfoChanged(taskInfo));
         if (mRootTaskInfo.taskId == taskInfo.taskId) {
             mRootTaskInfo = taskInfo;
+            boolean isVisible = taskInfo.isVisible && taskInfo.isVisibleRequested;
+            if (mVisible != isVisible) {
+                ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTaskInfoChanged: currentVis=%b newVis=%b",
+                        mVisible, isVisible);
+                mVisible = isVisible;
+                mCallbacks.onStageVisibilityChanged(this);
+            }
         } else if (taskInfo.parentTaskId == mRootTaskInfo.taskId) {
             if (!taskInfo.supportsMultiWindow
                     || !ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType())
@@ -260,7 +277,6 @@
                 return;
             }
             mChildrenTaskInfo.put(taskInfo.taskId, taskInfo);
-            mVisible = isStageVisible();
             mCallbacks.onChildTaskStatusChanged(this, taskInfo.taskId, true /* present */,
                     taskInfo.isVisible && taskInfo.isVisibleRequested);
         } else {
@@ -309,19 +325,6 @@
         t.reparent(sc, findTaskSurface(taskId));
     }
 
-    /**
-     * Checks against all children task info and return true if any are marked as visible.
-     */
-    private boolean isStageVisible() {
-        for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
-            if (mChildrenTaskInfo.valueAt(i).isVisible
-                    && mChildrenTaskInfo.valueAt(i).isVisibleRequested) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     private SurfaceControl findTaskSurface(int taskId) {
         if (mRootTaskInfo.taskId == taskId) {
             return mRootLeash;
@@ -350,12 +353,6 @@
         }
     }
 
-    void screenshotIfNeeded(SurfaceControl.Transaction t) {
-        if (mSplitDecorManager != null) {
-            mSplitDecorManager.screenshotIfNeeded(t);
-        }
-    }
-
     void fadeOutDecor(Runnable finishedCallback) {
         if (mSplitDecorManager != null) {
             mSplitDecorManager.fadeOutDecor(finishedCallback, false /* addDelay */);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitScreenController.java
index c5e158c..ea755306 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitScreenController.java
@@ -53,6 +53,7 @@
     private final SyncTransactionQueue mSyncQueue;
     private final Context mContext;
     private final ShellExecutor mMainExecutor;
+    private final ShellExecutor mBgExecutor;
     private final DisplayController mDisplayController;
     private final DisplayImeController mDisplayImeController;
     private final DisplayInsetsController mDisplayInsetsController;
@@ -85,18 +86,20 @@
             SplitState splitState,
             ShellExecutor mainExecutor,
             Handler mainHandler,
+            ShellExecutor bgExecutor,
             SystemWindows systemWindows) {
         super(context, shellInit, shellCommandHandler, shellController, shellTaskOrganizer,
                 syncQueue, rootTDAOrganizer, displayController, displayImeController,
                 displayInsetsController, null, transitions, transactionPool,
                 iconProvider, recentTasks, launchAdjacentController, Optional.empty(),
                 Optional.empty(), null /* stageCoordinator */, multiInstanceHelper, splitState,
-                mainExecutor, mainHandler);
-
+                mainExecutor, mainHandler, bgExecutor);
         mTaskOrganizer = shellTaskOrganizer;
         mSyncQueue = syncQueue;
         mContext = context;
         mMainExecutor = mainExecutor;
+        mMainHandler = mainHandler;
+        mBgExecutor = bgExecutor;
         mDisplayController = displayController;
         mDisplayImeController = displayImeController;
         mDisplayInsetsController = displayInsetsController;
@@ -106,8 +109,6 @@
         mRecentTasksOptional = recentTasks;
         mLaunchAdjacentController = launchAdjacentController;
         mSplitState = splitState;
-
-        mMainHandler = mainHandler;
         mSystemWindows = systemWindows;
     }
 
@@ -120,7 +121,7 @@
         return new TvStageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
                 mTaskOrganizer, mDisplayController, mDisplayImeController,
                 mDisplayInsetsController, mTransitions, mTransactionPool,
-                mIconProvider, mMainExecutor, mMainHandler,
+                mIconProvider, mMainExecutor, mMainHandler, mBgExecutor,
                 mRecentTasksOptional, mLaunchAdjacentController, mSplitState, mSystemWindows);
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvStageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvStageCoordinator.java
index ef1f88e..a318bcf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvStageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvStageCoordinator.java
@@ -51,15 +51,15 @@
             DisplayInsetsController displayInsetsController, Transitions transitions,
             TransactionPool transactionPool,
             IconProvider iconProvider, ShellExecutor mainExecutor,
-            Handler mainHandler,
+            Handler mainHandler, ShellExecutor bgExecutor,
             Optional<RecentTasksController> recentTasks,
             LaunchAdjacentController launchAdjacentController,
             SplitState splitState,
             SystemWindows systemWindows) {
         super(context, displayId, syncQueue, taskOrganizer, displayController, displayImeController,
                 displayInsetsController, transitions, transactionPool, iconProvider,
-                mainExecutor, mainHandler, recentTasks, launchAdjacentController, Optional.empty(),
-                splitState);
+                mainExecutor, mainHandler, bgExecutor, recentTasks, launchAdjacentController,
+                Optional.empty(), splitState);
 
         mTvSplitMenuController = new TvSplitMenuController(context, this,
                 systemWindows, mainHandler);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskView.java
index 82c0aaf..361d7663 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskView.java
@@ -186,6 +186,7 @@
      */
     public void setObscuredTouchRect(Rect obscuredRect) {
         mObscuredTouchRegion = obscuredRect != null ? new Region(obscuredRect) : null;
+        invalidate();
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
index 03ded73..b0547a2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
@@ -204,6 +204,7 @@
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
                 "tryAnimateOpenIntentWithRemoteAndPipOrDesktop");
         TransitionInfo.Change pipChange = null;
+        TransitionInfo.Change pipActivityChange = null;
         for (int i = info.getChanges().size() - 1; i >= 0; --i) {
             TransitionInfo.Change change = info.getChanges().get(i);
             if (mPipHandler.isEnteringPip(change, info.getType())) {
@@ -213,6 +214,12 @@
                 }
                 pipChange = change;
                 info.getChanges().remove(i);
+            } else if (change.getTaskInfo() == null && change.getParent() != null
+                    && pipChange != null && change.getParent().equals(pipChange.getContainer())) {
+                // Cache the PiP activity if it's a target and cached pip task change is its parent;
+                // note that we are bottom-to-top, so if such activity has a task
+                // that is also a target, then it must have been cached already as pipChange.
+                pipActivityChange = change;
             }
         }
         TransitionInfo.Change desktopChange = null;
@@ -257,8 +264,16 @@
             // make a new startTransaction because pip's startEnterAnimation "consumes" it so
             // we need a separate one to send over to launcher.
             SurfaceControl.Transaction otherStartT = new SurfaceControl.Transaction();
-
-            mPipHandler.startEnterAnimation(pipChange, otherStartT, finishTransaction, finishCB);
+            if (pipActivityChange == null) {
+                mPipHandler.startEnterAnimation(pipChange, otherStartT, finishTransaction,
+                        finishCB);
+            } else {
+                info.getChanges().remove(pipActivityChange);
+                TransitionInfo pipInfo = subCopy(info, TRANSIT_PIP, false /* withChanges */);
+                pipInfo.getChanges().addAll(List.of(pipChange, pipActivityChange));
+                mPipHandler.startAnimation(mTransition, pipInfo, startTransaction,
+                        finishTransaction, finishCB);
+            }
 
             // Dispatch the rest of the transition normally.
             if (mLeftoversHandler != null
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index 611f3e0..a7d6301 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -1076,9 +1076,11 @@
             @Nullable TransitionHandler skip
     ) {
         for (int i = mHandlers.size() - 1; i >= 0; --i) {
-            if (mHandlers.get(i) == skip) continue;
-            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " try handler %s",
-                    mHandlers.get(i));
+            if (mHandlers.get(i) == skip) {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " skip handler %s",
+                        mHandlers.get(i));
+                continue;
+            }
             boolean consumed = mHandlers.get(i).startAnimation(transition, info, startT, finishT,
                     finishCB);
             if (consumed) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt
index 4d95cde..01fc644 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt
@@ -19,19 +19,18 @@
 import android.app.ActivityManager.RunningTaskInfo
 import android.content.Context
 import android.graphics.Point
-import android.graphics.Rect
+import android.view.View
 import android.view.WindowManager
 import android.window.TaskSnapshot
 import androidx.compose.ui.graphics.toArgb
+import com.android.wm.shell.R
 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import com.android.wm.shell.shared.multiinstance.ManageWindowsViewContainer
-import com.android.wm.shell.shared.split.SplitScreenConstants
 import com.android.wm.shell.splitscreen.SplitScreenController
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewContainer
+import com.android.wm.shell.windowdecor.common.calculateMenuPosition
 import com.android.wm.shell.windowdecor.common.DecorThemeUtil
-import com.android.wm.shell.windowdecor.extension.isFullscreen
-import com.android.wm.shell.windowdecor.extension.isMultiWindow
 
 /**
  * Implementation of [ManageWindowsViewContainer] meant to be used in desktop header and app
@@ -59,35 +58,19 @@
     }
 
     private fun calculateMenuPosition(): Point {
-        val position = Point()
-        val nonFreeformX = (captionX + (captionWidth / 2) - (menuView.menuWidth / 2))
-        when {
-            callerTaskInfo.isFreeform -> {
-                val taskBounds = callerTaskInfo.getConfiguration().windowConfiguration.bounds
-                position.set(taskBounds.left, taskBounds.top)
-            }
-            callerTaskInfo.isFullscreen -> {
-                position.set(nonFreeformX, 0)
-            }
-            callerTaskInfo.isMultiWindow -> {
-                val splitPosition = splitScreenController.getSplitPosition(callerTaskInfo.taskId)
-                val leftOrTopStageBounds = Rect()
-                val rightOrBottomStageBounds = Rect()
-                splitScreenController.getStageBounds(leftOrTopStageBounds, rightOrBottomStageBounds)
-                // TODO(b/343561161): This needs to be calculated differently if the task is in
-                //  top/bottom split.
-                when (splitPosition) {
-                    SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT -> {
-                        position.set(leftOrTopStageBounds.width() + nonFreeformX, /* y= */ 0)
-                    }
-
-                    SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT -> {
-                        position.set(nonFreeformX, /* y= */ 0)
-                    }
-                }
-            }
-        }
-        return position
+        return calculateMenuPosition(
+            splitScreenController,
+            callerTaskInfo,
+            marginStart = 0,
+            marginTop = context.resources.getDimensionPixelSize(
+                R.dimen.desktop_mode_handle_menu_margin_top
+            ),
+            captionX,
+            0,
+            captionWidth,
+            menuView.menuWidth,
+            context.isRtl()
+        )
     }
 
     override fun addToContainer(menuView: ManageWindowsView) {
@@ -109,4 +92,7 @@
     override fun removeFromContainer() {
         menuViewContainer?.releaseView()
     }
+
+    private fun Context.isRtl() =
+        resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL
 }
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 0f5813c..5a05861 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
@@ -140,6 +140,7 @@
 import com.android.wm.shell.transition.FocusTransitionObserver;
 import com.android.wm.shell.transition.Transitions;
 import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.ExclusionRegionListener;
+import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader;
 import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost;
 import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHostSupplier;
 import com.android.wm.shell.windowdecor.extension.InsetsStateKt;
@@ -150,7 +151,9 @@
 import kotlin.Unit;
 import kotlin.jvm.functions.Function1;
 
+import kotlinx.coroutines.CoroutineScope;
 import kotlinx.coroutines.ExperimentalCoroutinesApi;
+import kotlinx.coroutines.MainCoroutineDispatcher;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -177,6 +180,8 @@
     private final ShellController mShellController;
     private final Context mContext;
     private final @ShellMainThread Handler mMainHandler;
+    private final @ShellMainThread MainCoroutineDispatcher mMainDispatcher;
+    private final @ShellBackgroundThread CoroutineScope mBgScope;
     private final @ShellBackgroundThread ShellExecutor mBgExecutor;
     private final Choreographer mMainChoreographer;
     private final DisplayController mDisplayController;
@@ -241,12 +246,15 @@
     private final FocusTransitionObserver mFocusTransitionObserver;
     private final DesktopModeEventLogger mDesktopModeEventLogger;
     private final DesktopModeUiEventLogger mDesktopModeUiEventLogger;
+    private final WindowDecorTaskResourceLoader mTaskResourceLoader;
 
     public DesktopModeWindowDecorViewModel(
             Context context,
             ShellExecutor shellExecutor,
             @ShellMainThread Handler mainHandler,
             Choreographer mainChoreographer,
+            @ShellMainThread MainCoroutineDispatcher mainDispatcher,
+            @ShellBackgroundThread CoroutineScope bgScope,
             @ShellBackgroundThread ShellExecutor bgExecutor,
             ShellInit shellInit,
             ShellCommandHandler shellCommandHandler,
@@ -273,12 +281,15 @@
             Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
             FocusTransitionObserver focusTransitionObserver,
             DesktopModeEventLogger desktopModeEventLogger,
-            DesktopModeUiEventLogger desktopModeUiEventLogger) {
+            DesktopModeUiEventLogger desktopModeUiEventLogger,
+            WindowDecorTaskResourceLoader taskResourceLoader) {
         this(
                 context,
                 shellExecutor,
                 mainHandler,
                 mainChoreographer,
+                mainDispatcher,
+                bgScope,
                 bgExecutor,
                 shellInit,
                 shellCommandHandler,
@@ -311,7 +322,8 @@
                 new TaskPositionerFactory(),
                 focusTransitionObserver,
                 desktopModeEventLogger,
-                desktopModeUiEventLogger);
+                desktopModeUiEventLogger,
+                taskResourceLoader);
     }
 
     @VisibleForTesting
@@ -320,6 +332,8 @@
             ShellExecutor shellExecutor,
             @ShellMainThread Handler mainHandler,
             Choreographer mainChoreographer,
+            @ShellMainThread MainCoroutineDispatcher mainDispatcher,
+            @ShellBackgroundThread CoroutineScope bgScope,
             @ShellBackgroundThread ShellExecutor bgExecutor,
             ShellInit shellInit,
             ShellCommandHandler shellCommandHandler,
@@ -352,11 +366,14 @@
             TaskPositionerFactory taskPositionerFactory,
             FocusTransitionObserver focusTransitionObserver,
             DesktopModeEventLogger desktopModeEventLogger,
-            DesktopModeUiEventLogger desktopModeUiEventLogger) {
+            DesktopModeUiEventLogger desktopModeUiEventLogger,
+            WindowDecorTaskResourceLoader taskResourceLoader) {
         mContext = context;
         mMainExecutor = shellExecutor;
         mMainHandler = mainHandler;
         mMainChoreographer = mainChoreographer;
+        mMainDispatcher = mainDispatcher;
+        mBgScope = bgScope;
         mBgExecutor = bgExecutor;
         mActivityTaskManager = mContext.getSystemService(ActivityTaskManager.class);
         mTaskOrganizer = taskOrganizer;
@@ -418,6 +435,7 @@
         mFocusTransitionObserver = focusTransitionObserver;
         mDesktopModeEventLogger = desktopModeEventLogger;
         mDesktopModeUiEventLogger = desktopModeUiEventLogger;
+        mTaskResourceLoader = taskResourceLoader;
 
         shellInit.addInitCallback(this::onInit, this);
     }
@@ -717,7 +735,8 @@
         // App sometimes draws before the insets from WindowDecoration#relayout have
         // been added, so they must be added here
         decoration.addCaptionInset(wct);
-        mDesktopTasksController.moveTaskToDesktop(taskId, wct, source);
+        mDesktopTasksController.moveTaskToDesktop(taskId, wct, source,
+                /* remoteTransition= */ null);
         decoration.closeHandleMenu();
 
         if (source == DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON) {
@@ -1639,12 +1658,16 @@
                                 : mContext,
                         mContext.createContextAsUser(UserHandle.of(taskInfo.userId), 0 /* flags */),
                         mDisplayController,
+                        mTaskResourceLoader,
                         mSplitScreenController,
                         mDesktopUserRepositories,
                         mTaskOrganizer,
                         taskInfo,
                         taskSurface,
                         mMainHandler,
+                        mMainExecutor,
+                        mMainDispatcher,
+                        mBgScope,
                         mBgExecutor,
                         mMainChoreographer,
                         mSyncQueue,
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 6562f38..febf566 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
@@ -28,7 +28,6 @@
 import static android.window.DesktopModeFlags.ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION_ALWAYS;
 
 
-import static com.android.launcher3.icons.BaseIconFactory.MODE_DEFAULT;
 import static com.android.wm.shell.shared.desktopmode.DesktopModeStatus.canEnterDesktopMode;
 import static com.android.wm.shell.shared.desktopmode.DesktopModeStatus.canEnterDesktopModeOrShowAppHandle;
 import static com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON;
@@ -49,9 +48,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -60,13 +56,11 @@
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.Region;
-import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.util.Size;
-import android.util.Slog;
 import android.view.Choreographer;
 import android.view.InsetsState;
 import android.view.MotionEvent;
@@ -81,8 +75,6 @@
 import android.window.WindowContainerTransaction;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.launcher3.icons.BaseIconFactory;
-import com.android.launcher3.icons.IconProvider;
 import com.android.window.flags.Flags;
 import com.android.wm.shell.R;
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
@@ -98,13 +90,16 @@
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.desktopmode.CaptionState;
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
+import com.android.wm.shell.desktopmode.DesktopModeUtils;
 import com.android.wm.shell.desktopmode.DesktopUserRepositories;
 import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository;
 import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
+import com.android.wm.shell.shared.annotations.ShellMainThread;
 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource;
 import com.android.wm.shell.shared.multiinstance.ManageWindowsViewContainer;
 import com.android.wm.shell.splitscreen.SplitScreenController;
+import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader;
 import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost;
 import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHostSupplier;
 import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
@@ -117,7 +112,11 @@
 import kotlin.jvm.functions.Function0;
 import kotlin.jvm.functions.Function1;
 
+import kotlinx.coroutines.CoroutineScope;
+import kotlinx.coroutines.MainCoroutineDispatcher;
+
 import java.util.List;
+import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 
@@ -133,12 +132,16 @@
     @VisibleForTesting
     static final long CLOSE_MAXIMIZE_MENU_DELAY_MS = 150L;
 
-    private final Handler mHandler;
+    private final @ShellMainThread Handler mHandler;
+    private final @ShellMainThread ShellExecutor mMainExecutor;
+    private final @ShellMainThread MainCoroutineDispatcher mMainDispatcher;
+    private final @ShellBackgroundThread CoroutineScope mBgScope;
     private final @ShellBackgroundThread ShellExecutor mBgExecutor;
     private final Choreographer mChoreographer;
     private final SyncTransactionQueue mSyncQueue;
     private final SplitScreenController mSplitScreenController;
     private final WindowManagerWrapper mWindowManagerWrapper;
+    private final @NonNull WindowDecorTaskResourceLoader mTaskResourceLoader;
 
     private WindowDecorationViewHolder mWindowDecorViewHolder;
     private View.OnClickListener mOnCaptionButtonClickListener;
@@ -174,10 +177,7 @@
     private OpenByDefaultDialog mOpenByDefaultDialog;
 
     private ResizeVeil mResizeVeil;
-    private Bitmap mAppIconBitmap;
-    private Bitmap mResizeVeilBitmap;
 
-    private CharSequence mAppName;
     private CapturedLink mCapturedLink;
     private Uri mGenericLink;
     private Uri mWebUri;
@@ -204,16 +204,23 @@
     private final WindowDecorCaptionHandleRepository mWindowDecorCaptionHandleRepository;
     private final DesktopUserRepositories mDesktopUserRepositories;
 
+    private Runnable mLoadAppInfoRunnable;
+    private Runnable mSetAppInfoRunnable;
+
     public DesktopModeWindowDecoration(
             Context context,
             @NonNull Context userContext,
             DisplayController displayController,
+            @NonNull WindowDecorTaskResourceLoader taskResourceLoader,
             SplitScreenController splitScreenController,
             DesktopUserRepositories desktopUserRepositories,
             ShellTaskOrganizer taskOrganizer,
             ActivityManager.RunningTaskInfo taskInfo,
             SurfaceControl taskSurface,
-            Handler handler,
+            @ShellMainThread Handler handler,
+            @ShellMainThread ShellExecutor mainExecutor,
+            @ShellMainThread MainCoroutineDispatcher mainDispatcher,
+            @ShellBackgroundThread CoroutineScope bgScope,
             @ShellBackgroundThread ShellExecutor bgExecutor,
             Choreographer choreographer,
             SyncTransactionQueue syncQueue,
@@ -225,12 +232,13 @@
             MultiInstanceHelper multiInstanceHelper,
             WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
             DesktopModeEventLogger desktopModeEventLogger) {
-        this (context, userContext, displayController, splitScreenController,
+        this (context, userContext, displayController, taskResourceLoader, splitScreenController,
                 desktopUserRepositories, taskOrganizer, taskInfo, taskSurface, handler,
-                bgExecutor, choreographer, syncQueue, appHeaderViewHolderFactory,
-                rootTaskDisplayAreaOrganizer, genericLinksParser, assistContentRequester,
-                SurfaceControl.Builder::new, SurfaceControl.Transaction::new,
-                WindowContainerTransaction::new, SurfaceControl::new, new WindowManagerWrapper(
+                mainExecutor, mainDispatcher, bgScope, bgExecutor, choreographer, syncQueue,
+                appHeaderViewHolderFactory, rootTaskDisplayAreaOrganizer, genericLinksParser,
+                assistContentRequester, SurfaceControl.Builder::new,
+                SurfaceControl.Transaction::new, WindowContainerTransaction::new,
+                SurfaceControl::new, new WindowManagerWrapper(
                         context.getSystemService(WindowManager.class)),
                 new SurfaceControlViewHostFactory() {},
                 windowDecorViewHostSupplier,
@@ -243,12 +251,16 @@
             Context context,
             @NonNull Context userContext,
             DisplayController displayController,
+            @NonNull WindowDecorTaskResourceLoader taskResourceLoader,
             SplitScreenController splitScreenController,
             DesktopUserRepositories desktopUserRepositories,
             ShellTaskOrganizer taskOrganizer,
             ActivityManager.RunningTaskInfo taskInfo,
             SurfaceControl taskSurface,
-            Handler handler,
+            @ShellMainThread Handler handler,
+            @ShellMainThread ShellExecutor mainExecutor,
+            @ShellMainThread MainCoroutineDispatcher mainDispatcher,
+            @ShellBackgroundThread CoroutineScope bgScope,
             @ShellBackgroundThread ShellExecutor bgExecutor,
             Choreographer choreographer,
             SyncTransactionQueue syncQueue,
@@ -274,6 +286,9 @@
                 surfaceControlViewHostFactory, windowDecorViewHostSupplier, desktopModeEventLogger);
         mSplitScreenController = splitScreenController;
         mHandler = handler;
+        mMainExecutor = mainExecutor;
+        mMainDispatcher = mainDispatcher;
+        mBgScope = bgScope;
         mBgExecutor = bgExecutor;
         mChoreographer = choreographer;
         mSyncQueue = syncQueue;
@@ -287,6 +302,8 @@
         mWindowManagerWrapper = windowManagerWrapper;
         mWindowDecorCaptionHandleRepository = windowDecorCaptionHandleRepository;
         mDesktopUserRepositories = desktopUserRepositories;
+        mTaskResourceLoader = taskResourceLoader;
+        mTaskResourceLoader.onWindowDecorCreated(taskInfo);
     }
 
     /**
@@ -503,6 +520,14 @@
         if (oldRootView != mResult.mRootView) {
             disposeStatusBarInputLayer();
             mWindowDecorViewHolder = createViewHolder();
+            // Load these only when first creating the view.
+            loadTaskNameAndIconInBackground((name, icon) -> {
+                final AppHeaderViewHolder appHeader = asAppHeader(mWindowDecorViewHolder);
+                if (appHeader != null) {
+                    appHeader.setAppName(name);
+                    appHeader.setAppIcon(icon);
+                }
+            });
         }
 
         final Point position = new Point();
@@ -522,7 +547,7 @@
         } else {
             mWindowDecorViewHolder.bindData(new AppHeaderViewHolder.HeaderData(
                     mTaskInfo,
-                    TaskInfoKt.getRequestingImmersive(mTaskInfo),
+                    DesktopModeUtils.isTaskMaximized(mTaskInfo, mDisplayController),
                     inFullImmersive,
                     hasGlobalFocus,
                     /* maximizeHoverEnabled= */ canOpenMaximizeMenu(
@@ -541,6 +566,33 @@
         Trace.endSection(); // DesktopModeWindowDecoration#relayout
     }
 
+    /**
+     * Loads the task's name and icon in a background thread and posts the results back in the
+     * main thread.
+     */
+    private void loadTaskNameAndIconInBackground(BiConsumer<CharSequence, Bitmap> onResult) {
+        if (mWindowDecorViewHolder == null) return;
+        if (asAppHeader(mWindowDecorViewHolder) == null) {
+            // Only needed when drawing a header.
+            return;
+        }
+        if (mLoadAppInfoRunnable != null) {
+            mBgExecutor.removeCallbacks(mLoadAppInfoRunnable);
+        }
+        if (mSetAppInfoRunnable != null) {
+            mMainExecutor.removeCallbacks(mSetAppInfoRunnable);
+        }
+        mLoadAppInfoRunnable = () -> {
+            final CharSequence name = mTaskResourceLoader.getName(mTaskInfo);
+            final Bitmap icon = mTaskResourceLoader.getHeaderIcon(mTaskInfo);
+            mSetAppInfoRunnable = () -> {
+                onResult.accept(name, icon);
+            };
+            mMainExecutor.execute(mSetAppInfoRunnable);
+        };
+        mBgExecutor.execute(mLoadAppInfoRunnable);
+    }
+
     private boolean isCaptionVisible() {
         return mTaskInfo.isVisible && mIsCaptionVisible;
     }
@@ -556,10 +608,10 @@
     @Nullable
     private Intent getBrowserLink() {
         final Uri browserLink;
-        if (isCapturedLinkAvailable()) {
-            browserLink = mCapturedLink.mUri;
-        } else if (mWebUri != null) {
+        if (mWebUri != null) {
             browserLink = mWebUri;
+        } else if (isCapturedLinkAvailable()) {
+            browserLink = mCapturedLink.mUri;
         } else {
             browserLink = mGenericLink;
         }
@@ -760,15 +812,12 @@
             );
         } else if (mRelayoutParams.mLayoutResId
                 == R.layout.desktop_mode_app_header) {
-            loadAppInfoIfNeeded();
             return mAppHeaderViewHolderFactory.create(
                     mResult.mRootView,
                     mOnCaptionTouchListener,
                     mOnCaptionButtonClickListener,
                     mOnCaptionLongClickListener,
                     mOnCaptionGenericMotionListener,
-                    mAppName,
-                    mAppIconBitmap,
                     mOnMaximizeHoverListener);
         }
         throw new IllegalArgumentException("Unexpected layout resource id");
@@ -1032,7 +1081,10 @@
                 mTaskInfo,
                 mTaskSurface,
                 mDisplayController,
+                mTaskResourceLoader,
                 mSurfaceControlTransactionSupplier,
+                mMainDispatcher,
+                mBgScope,
                 new OpenByDefaultDialog.DialogLifecycleListener() {
                     @Override
                     public void onDialogCreated() {
@@ -1043,9 +1095,7 @@
                     public void onDialogDismissed() {
                         mOpenByDefaultDialog = null;
                     }
-                },
-                mAppIconBitmap,
-                mAppName
+                }
         );
     }
 
@@ -1057,50 +1107,6 @@
         return mDragResizeListener != null && mDragResizeListener.isHandlingDragResize();
     }
 
-    private void loadAppInfoIfNeeded() {
-        // TODO(b/337370277): move this to another thread.
-        try {
-            Trace.beginSection("DesktopModeWindowDecoration#loadAppInfoIfNeeded");
-            if (mAppIconBitmap != null && mAppName != null) {
-                return;
-            }
-            if (mTaskInfo.baseIntent == null) {
-                Slog.e(TAG, "Base intent not found in task");
-                return;
-            }
-            final PackageManager pm = mUserContext.getPackageManager();
-            final ActivityInfo activityInfo =
-                    pm.getActivityInfo(mTaskInfo.baseIntent.getComponent(), 0 /* flags */);
-            final IconProvider provider = new IconProvider(mContext);
-            final Drawable appIconDrawable = provider.getIcon(activityInfo);
-            final Drawable badgedAppIconDrawable = pm.getUserBadgedIcon(appIconDrawable,
-                    UserHandle.of(mTaskInfo.userId));
-            final BaseIconFactory headerIconFactory = createIconFactory(mContext,
-                    R.dimen.desktop_mode_caption_icon_radius);
-            mAppIconBitmap = headerIconFactory.createIconBitmap(badgedAppIconDrawable,
-                    1f /* scale */);
-
-            final BaseIconFactory resizeVeilIconFactory = createIconFactory(mContext,
-                    R.dimen.desktop_mode_resize_veil_icon_size);
-            mResizeVeilBitmap = resizeVeilIconFactory
-                    .createScaledBitmap(appIconDrawable, MODE_DEFAULT);
-
-            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
-            mAppName = pm.getApplicationLabel(applicationInfo);
-        } catch (PackageManager.NameNotFoundException e) {
-            Slog.e(TAG, "Base activity's component name cannot be found on the system", e);
-        } finally {
-            Trace.endSection();
-        }
-    }
-
-    private BaseIconFactory createIconFactory(Context context, int dimensions) {
-        final Resources resources = context.getResources();
-        final int densityDpi = resources.getDisplayMetrics().densityDpi;
-        final int iconSize = resources.getDimensionPixelSize(dimensions);
-        return new BaseIconFactory(context, densityDpi, iconSize);
-    }
-
     private void closeDragResizeListener() {
         if (mDragResizeListener == null) {
             return;
@@ -1115,9 +1121,9 @@
      */
     private void createResizeVeilIfNeeded() {
         if (mResizeVeil != null) return;
-        loadAppInfoIfNeeded();
-        mResizeVeil = new ResizeVeil(mContext, mDisplayController, mResizeVeilBitmap,
-                mTaskSurface, mSurfaceControlTransactionSupplier, mTaskInfo);
+        mResizeVeil = new ResizeVeil(mContext, mDisplayController, mTaskResourceLoader,
+                mMainDispatcher, mBgScope, mTaskSurface,
+                mSurfaceControlTransactionSupplier, mTaskInfo);
     }
 
     /**
@@ -1316,8 +1322,7 @@
      */
     @VisibleForTesting
     void onAssistContentReceived(@Nullable AssistContent assistContent) {
-        mWebUri = assistContent == null ? null : assistContent.getWebUri();
-        loadAppInfoIfNeeded();
+        mWebUri = assistContent == null ? null : AppToWebUtils.getSessionWebUri(assistContent);
         updateGenericLink();
         final boolean supportsMultiInstance = mMultiInstanceHelper
                 .supportsMultiInstanceSplit(mTaskInfo.baseActivity)
@@ -1330,11 +1335,12 @@
                 .isTaskInFullImmersiveState(mTaskInfo.taskId);
         final boolean isBrowserApp = isBrowserApp();
         mHandleMenu = mHandleMenuFactory.create(
+                mMainDispatcher,
+                mBgScope,
                 this,
                 mWindowManagerWrapper,
+                mTaskResourceLoader,
                 mRelayoutParams.mLayoutResId,
-                mAppIconBitmap,
-                mAppName,
                 mSplitScreenController,
                 canEnterDesktopModeOrShowAppHandle(mContext),
                 supportsMultiInstance,
@@ -1623,12 +1629,20 @@
 
     @Override
     public void close() {
+        if (mLoadAppInfoRunnable != null) {
+            mBgExecutor.removeCallbacks(mLoadAppInfoRunnable);
+        }
+        if (mSetAppInfoRunnable != null) {
+            mMainExecutor.removeCallbacks(mSetAppInfoRunnable);
+        }
+        mTaskResourceLoader.onWindowDecorClosed(mTaskInfo);
         closeDragResizeListener();
         closeHandleMenu();
         closeManageWindowsMenu();
         mExclusionRegionListener.onExclusionRegionDismissed(mTaskInfo.taskId);
         disposeResizeVeil();
         disposeStatusBarInputLayer();
+        mWindowDecorViewHolder = null;
         if (canEnterDesktopMode(mContext) && isEducationEnabled()) {
             notifyNoCaptionHandle();
         }
@@ -1705,7 +1719,7 @@
                         .isTaskInFullImmersiveState(mTaskInfo.taskId);
         asAppHeader(mWindowDecorViewHolder).bindData(new AppHeaderViewHolder.HeaderData(
                 mTaskInfo,
-                TaskInfoKt.getRequestingImmersive(mTaskInfo),
+                DesktopModeUtils.isTaskMaximized(mTaskInfo, mDisplayController),
                 inFullImmersive,
                 isFocused(),
                 /* maximizeHoverEnabled= */ canOpenMaximizeMenu(animatingTaskResizeOrReposition)));
@@ -1752,12 +1766,16 @@
                 Context context,
                 @NonNull Context userContext,
                 DisplayController displayController,
+                @NonNull WindowDecorTaskResourceLoader appResourceProvider,
                 SplitScreenController splitScreenController,
                 DesktopUserRepositories desktopUserRepositories,
                 ShellTaskOrganizer taskOrganizer,
                 ActivityManager.RunningTaskInfo taskInfo,
                 SurfaceControl taskSurface,
-                Handler handler,
+                @ShellMainThread Handler handler,
+                @ShellMainThread ShellExecutor mainExecutor,
+                @ShellMainThread MainCoroutineDispatcher mainDispatcher,
+                @ShellBackgroundThread CoroutineScope bgScope,
                 @ShellBackgroundThread ShellExecutor bgExecutor,
                 Choreographer choreographer,
                 SyncTransactionQueue syncQueue,
@@ -1774,12 +1792,16 @@
                     context,
                     userContext,
                     displayController,
+                    appResourceProvider,
                     splitScreenController,
                     desktopUserRepositories,
                     taskOrganizer,
                     taskInfo,
                     taskSurface,
                     handler,
+                    mainExecutor,
+                    mainDispatcher,
+                    bgScope,
                     bgExecutor,
                     choreographer,
                     syncQueue,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
index 049b8d6..159759e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
@@ -47,15 +47,25 @@
 import androidx.core.view.isGone
 import com.android.window.flags.Flags
 import com.android.wm.shell.R
-import com.android.wm.shell.apptoweb.isBrowserApp
+import com.android.wm.shell.shared.annotations.ShellBackgroundThread
+import com.android.wm.shell.shared.annotations.ShellMainThread
 import com.android.wm.shell.shared.split.SplitScreenConstants
 import com.android.wm.shell.splitscreen.SplitScreenController
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewContainer
 import com.android.wm.shell.windowdecor.common.DecorThemeUtil
+import com.android.wm.shell.windowdecor.common.calculateMenuPosition
+import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader
 import com.android.wm.shell.windowdecor.extension.isFullscreen
 import com.android.wm.shell.windowdecor.extension.isMultiWindow
 import com.android.wm.shell.windowdecor.extension.isPinned
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.MainCoroutineDispatcher
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 
 /**
  * Handle menu opened when the appropriate button is clicked on.
@@ -66,11 +76,12 @@
  * Additional Options: Miscellaneous functions including screenshot and closing task.
  */
 class HandleMenu(
+    @ShellMainThread private val mainDispatcher: CoroutineDispatcher,
+    @ShellBackgroundThread private val bgScope: CoroutineScope,
     private val parentDecor: DesktopModeWindowDecoration,
     private val windowManagerWrapper: WindowManagerWrapper,
+    private val taskResourceLoader: WindowDecorTaskResourceLoader,
     private val layoutResId: Int,
-    private val appIconBitmap: Bitmap?,
-    private val appName: CharSequence?,
     private val splitScreenController: SplitScreenController,
     private val shouldShowWindowingPill: Boolean,
     private val shouldShowNewWindowButton: Boolean,
@@ -103,7 +114,8 @@
 
     @VisibleForTesting
     var handleMenuViewContainer: AdditionalViewContainer? = null
-    private var handleMenuView: HandleMenuView? = null
+    @VisibleForTesting
+    var handleMenuView: HandleMenuView? = null
 
     // Position of the handle menu used for laying out the handle view.
     @VisibleForTesting
@@ -122,6 +134,8 @@
         get() = SHOULD_SHOW_SCREENSHOT_BUTTON || shouldShowNewWindowButton ||
             shouldShowManageWindowsButton || shouldShowChangeAspectRatioButton
 
+    private var loadAppInfoJob: Job? = null
+
     init {
         updateHandleMenuPillPositions(captionX, captionY)
     }
@@ -190,7 +204,7 @@
             shouldShowDesktopModeButton = shouldShowDesktopModeButton,
             isBrowserApp = isBrowserApp
         ).apply {
-            bind(taskInfo, appIconBitmap, appName, shouldShowMoreActionsPill)
+            bind(taskInfo, shouldShowMoreActionsPill)
             this.onToDesktopClickListener = onToDesktopClickListener
             this.onToFullscreenClickListener = onToFullscreenClickListener
             this.onToSplitScreenClickListener = onToSplitScreenClickListener
@@ -204,7 +218,16 @@
             this.onCloseMenuClickListener = onCloseMenuClickListener
             this.onOutsideTouchListener = onOutsideTouchListener
         }
-
+        loadAppInfoJob = bgScope.launch {
+            if (!isActive) return@launch
+            val name = taskResourceLoader.getName(taskInfo)
+            val icon = taskResourceLoader.getHeaderIcon(taskInfo)
+            withContext(mainDispatcher) {
+                if (!isActive) return@withContext
+                handleMenuView.setAppName(name)
+                handleMenuView.setAppIcon(icon)
+            }
+        }
         val x = handleMenuPosition.x.toInt()
         val y = handleMenuPosition.y.toInt()
         handleMenuViewContainer =
@@ -240,7 +263,19 @@
         val menuX: Int
         val menuY: Int
         val taskBounds = taskInfo.getConfiguration().windowConfiguration.bounds
-        updateGlobalMenuPosition(taskBounds, captionX, captionY)
+        globalMenuPosition.set(
+            calculateMenuPosition(
+                splitScreenController,
+                taskInfo,
+                marginStart = marginMenuStart,
+                marginMenuTop,
+                captionX,
+                captionY,
+                captionWidth,
+                menuWidth,
+                context.isRtl()
+            )
+        )
         if (layoutResId == R.layout.desktop_mode_app_header) {
             // Align the handle menu to the start of the header.
             menuX = if (context.isRtl()) {
@@ -265,53 +300,6 @@
         handleMenuPosition.set(menuX.toFloat(), menuY.toFloat())
     }
 
-    private fun updateGlobalMenuPosition(taskBounds: Rect, captionX: Int, captionY: Int) {
-        val nonFreeformX = captionX + (captionWidth / 2) - (menuWidth / 2)
-        when {
-            taskInfo.isFreeform -> {
-                if (context.isRtl()) {
-                    globalMenuPosition.set(
-                        /* x= */ taskBounds.right - menuWidth - marginMenuStart,
-                        /* y= */ taskBounds.top + captionY + marginMenuTop
-                    )
-                } else {
-                    globalMenuPosition.set(
-                        /* x= */ taskBounds.left + marginMenuStart,
-                        /* y= */ taskBounds.top + captionY + marginMenuTop
-                    )
-                }
-            }
-            taskInfo.isFullscreen -> {
-                globalMenuPosition.set(
-                    /* x = */ nonFreeformX,
-                    /* y = */ marginMenuTop + captionY
-                )
-            }
-            taskInfo.isMultiWindow -> {
-                val splitPosition = splitScreenController.getSplitPosition(taskInfo.taskId)
-                val leftOrTopStageBounds = Rect()
-                val rightOrBottomStageBounds = Rect()
-                splitScreenController.getStageBounds(leftOrTopStageBounds, rightOrBottomStageBounds)
-                // TODO(b/343561161): This needs to be calculated differently if the task is in
-                //  top/bottom split.
-                when (splitPosition) {
-                    SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT -> {
-                        globalMenuPosition.set(
-                            /* x = */ leftOrTopStageBounds.width() + nonFreeformX,
-                            /* y = */ captionY + marginMenuTop
-                        )
-                    }
-                    SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT -> {
-                        globalMenuPosition.set(
-                            /* x = */ nonFreeformX,
-                            /* y = */ captionY + marginMenuTop
-                        )
-                    }
-                }
-            }
-        }
-    }
-
     /**
      * Update pill layout, in case task changes have caused positioning to change.
      */
@@ -374,8 +362,6 @@
             )
             if (splitScreenController.getSplitPosition(taskInfo.taskId)
                 == SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT) {
-                // TODO(b/343561161): This also needs to be calculated differently if
-                //  the task is in top/bottom split.
                 val leftStageBounds = Rect()
                 splitScreenController.getStageBounds(leftStageBounds, Rect())
                 inputRelativeToMenu.x += leftStageBounds.width().toFloat()
@@ -449,6 +435,7 @@
         resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL
 
     fun close() {
+        loadAppInfoJob?.cancel()
         handleMenuView?.animateCloseMenu {
             handleMenuViewContainer?.releaseView()
             handleMenuViewContainer = null
@@ -476,8 +463,10 @@
         private val appInfoPill = rootView.requireViewById<View>(R.id.app_info_pill)
         private val collapseMenuButton = appInfoPill.requireViewById<HandleMenuImageButton>(
             R.id.collapse_menu_button)
-        private val appIconView = appInfoPill.requireViewById<ImageView>(R.id.application_icon)
-        private val appNameView = appInfoPill.requireViewById<TextView>(R.id.application_name)
+        @VisibleForTesting
+        val appIconView = appInfoPill.requireViewById<ImageView>(R.id.application_icon)
+        @VisibleForTesting
+        val appNameView = appInfoPill.requireViewById<TextView>(R.id.application_name)
 
         // Windowing Pill.
         private val windowingPill = rootView.requireViewById<View>(R.id.windowing_pill)
@@ -546,14 +535,12 @@
         /** Binds the menu views to the new data. */
         fun bind(
             taskInfo: RunningTaskInfo,
-            appIconBitmap: Bitmap?,
-            appName: CharSequence?,
             shouldShowMoreActionsPill: Boolean
         ) {
             this.taskInfo = taskInfo
             this.style = calculateMenuStyle(taskInfo)
 
-            bindAppInfoPill(style, appIconBitmap, appName)
+            bindAppInfoPill(style)
             if (shouldShowWindowingPill) {
                 bindWindowingPill(style)
             }
@@ -564,6 +551,16 @@
             bindOpenInAppOrBrowserPill(style)
         }
 
+        /** Sets the app's name. */
+        fun setAppName(name: CharSequence) {
+            appNameView.text = name
+        }
+
+        /** Sets the app's icon. */
+        fun setAppIcon(icon: Bitmap) {
+            appIconView.setImageBitmap(icon)
+        }
+
         /** Animates the menu openInAppOrBrowserg. */
         fun animateOpenMenu() {
             if (taskInfo.isFullscreen || taskInfo.isMultiWindow) {
@@ -630,22 +627,14 @@
             )
         }
 
-        private fun bindAppInfoPill(
-            style: MenuStyle,
-            appIconBitmap: Bitmap?,
-            appName: CharSequence?
-        ) {
+        private fun bindAppInfoPill(style: MenuStyle) {
             appInfoPill.background.setTint(style.backgroundColor)
 
             collapseMenuButton.apply {
                 imageTintList = ColorStateList.valueOf(style.textColor)
                 this.taskInfo = this@HandleMenuView.taskInfo
             }
-            appIconView.setImageBitmap(appIconBitmap)
-            appNameView.apply {
-                text = appName
-                setTextColor(style.textColor)
-            }
+            appNameView.setTextColor(style.textColor)
         }
 
         private fun bindWindowingPill(style: MenuStyle) {
@@ -735,11 +724,12 @@
 /** A factory interface to create a [HandleMenu]. */
 interface HandleMenuFactory {
     fun create(
+        @ShellMainThread mainDispatcher: MainCoroutineDispatcher,
+        @ShellBackgroundThread bgScope: CoroutineScope,
         parentDecor: DesktopModeWindowDecoration,
         windowManagerWrapper: WindowManagerWrapper,
+        taskResourceLoader: WindowDecorTaskResourceLoader,
         layoutResId: Int,
-        appIconBitmap: Bitmap?,
-        appName: CharSequence?,
         splitScreenController: SplitScreenController,
         shouldShowWindowingPill: Boolean,
         shouldShowNewWindowButton: Boolean,
@@ -758,11 +748,12 @@
 /** A [HandleMenuFactory] implementation that creates a [HandleMenu].  */
 object DefaultHandleMenuFactory : HandleMenuFactory {
     override fun create(
+        @ShellMainThread mainDispatcher: MainCoroutineDispatcher,
+        @ShellBackgroundThread bgScope: CoroutineScope,
         parentDecor: DesktopModeWindowDecoration,
         windowManagerWrapper: WindowManagerWrapper,
+        taskResourceLoader: WindowDecorTaskResourceLoader,
         layoutResId: Int,
-        appIconBitmap: Bitmap?,
-        appName: CharSequence?,
         splitScreenController: SplitScreenController,
         shouldShowWindowingPill: Boolean,
         shouldShowNewWindowButton: Boolean,
@@ -777,11 +768,12 @@
         captionY: Int,
     ): HandleMenu {
         return HandleMenu(
+            mainDispatcher,
+            bgScope,
             parentDecor,
             windowManagerWrapper,
+            taskResourceLoader,
             layoutResId,
-            appIconBitmap,
-            appName,
             splitScreenController,
             shouldShowWindowingPill,
             shouldShowNewWindowButton,
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 11a7cf8..cc54d25 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
@@ -63,7 +63,7 @@
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.SyncTransactionQueue
-import com.android.wm.shell.desktopmode.calculateMaximizeBounds
+import com.android.wm.shell.desktopmode.isTaskMaximized
 import com.android.wm.shell.shared.animation.Interpolators.EMPHASIZED_DECELERATE
 import com.android.wm.shell.shared.animation.Interpolators.FAST_OUT_LINEAR_IN
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewHostViewContainer
@@ -231,11 +231,7 @@
     }
 
     private fun getSizeToggleDirection(): MaximizeMenuView.SizeToggleDirection {
-        val maximizeBounds = calculateMaximizeBounds(
-            displayController.getDisplayLayout(taskInfo.displayId)!!,
-            taskInfo
-        )
-        val maximized = taskInfo.configuration.windowConfiguration.bounds.equals(maximizeBounds)
+        val maximized = isTaskMaximized(taskInfo, displayController)
         return if (maximized)
             MaximizeMenuView.SizeToggleDirection.RESTORE
         else
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.kt
index 8770d35..96839ce 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.kt
@@ -20,7 +20,6 @@
 import android.animation.ValueAnimator
 import android.app.ActivityManager.RunningTaskInfo
 import android.content.Context
-import android.graphics.Bitmap
 import android.graphics.Color
 import android.graphics.PixelFormat
 import android.graphics.PointF
@@ -38,13 +37,23 @@
 import androidx.compose.material3.dynamicDarkColorScheme
 import androidx.compose.material3.dynamicLightColorScheme
 import androidx.compose.ui.graphics.toArgb
+import com.android.internal.annotations.VisibleForTesting
 import com.android.wm.shell.R
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.DisplayController.OnDisplaysChangedListener
+import com.android.wm.shell.shared.annotations.ShellBackgroundThread
+import com.android.wm.shell.shared.annotations.ShellMainThread
 import com.android.wm.shell.windowdecor.WindowDecoration.SurfaceControlViewHostFactory
+import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader
 import com.android.wm.shell.windowdecor.common.DecorThemeUtil
 import com.android.wm.shell.windowdecor.common.Theme
 import java.util.function.Supplier
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 
 /**
  * Creates and updates a veil that covers task contents on resize.
@@ -52,7 +61,9 @@
 public class ResizeVeil @JvmOverloads constructor(
         private val context: Context,
         private val displayController: DisplayController,
-        private val appIcon: Bitmap,
+        private val taskResourceLoader: WindowDecorTaskResourceLoader,
+        @ShellMainThread private val mainDispatcher: CoroutineDispatcher,
+        @ShellBackgroundThread private val bgScope: CoroutineScope,
         private var parentSurface: SurfaceControl,
         private val surfaceControlTransactionSupplier: Supplier<SurfaceControl.Transaction>,
         private val surfaceControlBuilderFactory: SurfaceControlBuilderFactory =
@@ -65,7 +76,8 @@
     private val lightColors = dynamicLightColorScheme(context)
     private val darkColors = dynamicDarkColorScheme(context)
 
-    private lateinit var iconView: ImageView
+    @VisibleForTesting
+    lateinit var iconView: ImageView
     private var iconSize = 0
 
     /** A container surface to host the veil background and icon child surfaces.  */
@@ -77,6 +89,7 @@
     private var viewHost: SurfaceControlViewHost? = null
     private var display: Display? = null
     private var veilAnimator: ValueAnimator? = null
+    private var loadAppInfoJob: Job? = null
 
     /**
      * Whether the resize veil is currently visible.
@@ -142,7 +155,6 @@
         val root = LayoutInflater.from(context)
                 .inflate(R.layout.desktop_mode_resize_veil, null /* root */)
         iconView = root.requireViewById(R.id.veil_application_icon)
-        iconView.setImageBitmap(appIcon)
         val lp = WindowManager.LayoutParams(
                 iconSize,
                 iconSize,
@@ -156,6 +168,14 @@
                 iconSurface, null /* hostInputToken */)
         viewHost = surfaceControlViewHostFactory.create(context, display, wwm, "ResizeVeil")
         viewHost?.setView(root, lp)
+        loadAppInfoJob = bgScope.launch {
+            if (!isActive) return@launch
+            val icon = taskResourceLoader.getVeilIcon(taskInfo)
+            withContext(mainDispatcher) {
+                if (!isActive) return@withContext
+                iconView.setImageBitmap(icon)
+            }
+        }
         Trace.endSection()
     }
 
@@ -401,6 +421,7 @@
         cancelAnimation()
         veilAnimator = null
         isVisible = false
+        loadAppInfoJob?.cancel()
 
         viewHost?.release()
         viewHost = null
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/DesktopMenuPositionUtility.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/DesktopMenuPositionUtility.kt
new file mode 100644
index 0000000..6def3da
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/DesktopMenuPositionUtility.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.wm.shell.windowdecor.common
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.graphics.Point
+import android.graphics.Rect
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
+import com.android.wm.shell.splitscreen.SplitScreenController
+import com.android.wm.shell.windowdecor.extension.isFullscreen
+
+/** Utility function used for calculating position of desktop mode menus. */
+fun calculateMenuPosition(
+    splitScreenController: SplitScreenController,
+    taskInfo: RunningTaskInfo,
+    marginStart: Int,
+    marginTop: Int,
+    captionX: Int,
+    captionY: Int,
+    captionWidth: Int,
+    menuWidth: Int,
+    isRtl: Boolean,
+): Point {
+    if (taskInfo.isFreeform) {
+        val taskBounds = taskInfo.configuration.windowConfiguration.bounds
+        return if (isRtl) {
+            Point(
+                /* x= */ taskBounds.right - menuWidth - marginStart,
+                /* y= */ taskBounds.top + marginTop,
+            )
+        } else {
+            Point(/* x= */ taskBounds.left + marginStart, /* y= */ taskBounds.top + marginTop)
+        }
+    }
+    val nonFreeformPosition = Point(captionX + (captionWidth / 2) - (menuWidth / 2), captionY)
+    if (taskInfo.isFullscreen) {
+        return Point(nonFreeformPosition.x, nonFreeformPosition.y + marginTop)
+    }
+    // Only the splitscreen case left.
+    val splitPosition = splitScreenController.getSplitPosition(taskInfo.taskId)
+    val leftOrTopStageBounds = Rect()
+    val rightOrBottomStageBounds = Rect()
+    splitScreenController.getRefStageBounds(leftOrTopStageBounds, rightOrBottomStageBounds)
+    if (splitScreenController.isLeftRightSplit) {
+        val rightStageModifier =
+            if (splitPosition == SPLIT_POSITION_BOTTOM_OR_RIGHT) {
+                rightOrBottomStageBounds.left
+            } else {
+                0
+            }
+        return Point(
+            /* x = */ rightStageModifier + nonFreeformPosition.x,
+            /* y = */ nonFreeformPosition.y + marginTop,
+        )
+    } else {
+        val bottomSplitModifier =
+            if (splitPosition == SPLIT_POSITION_BOTTOM_OR_RIGHT) {
+                rightOrBottomStageBounds.top
+            } else {
+                0
+            }
+        return Point(
+            /* x = */ nonFreeformPosition.x,
+            /* y = */ nonFreeformPosition.y + bottomSplitModifier + marginTop,
+        )
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/WindowDecorTaskResourceLoader.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/WindowDecorTaskResourceLoader.kt
new file mode 100644
index 0000000..d87da09
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/WindowDecorTaskResourceLoader.kt
@@ -0,0 +1,199 @@
+/*
+ * 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.common
+
+import android.annotation.DimenRes
+import android.app.ActivityManager
+import android.app.ActivityManager.RunningTaskInfo
+import android.content.Context
+import android.content.pm.ActivityInfo
+import android.content.pm.PackageManager
+import android.graphics.Bitmap
+import android.os.UserHandle
+import androidx.tracing.Trace
+import com.android.internal.annotations.VisibleForTesting
+import com.android.launcher3.icons.BaseIconFactory
+import com.android.launcher3.icons.BaseIconFactory.MODE_DEFAULT
+import com.android.launcher3.icons.IconProvider
+import com.android.wm.shell.R
+import com.android.wm.shell.shared.annotations.ShellBackgroundThread
+import com.android.wm.shell.sysui.ShellCommandHandler
+import com.android.wm.shell.sysui.ShellController
+import com.android.wm.shell.sysui.ShellInit
+import com.android.wm.shell.sysui.UserChangeListener
+import java.io.PrintWriter
+import java.util.concurrent.ConcurrentHashMap
+
+/**
+ * A utility and cache for window decoration UI resources.
+ */
+class WindowDecorTaskResourceLoader(
+    private val context: Context,
+    shellInit: ShellInit,
+    private val shellController: ShellController,
+    private val shellCommandHandler: ShellCommandHandler,
+    private val iconProvider: IconProvider,
+    private val headerIconFactory: BaseIconFactory,
+    private val veilIconFactory: BaseIconFactory,
+) {
+    constructor(
+        context: Context,
+        shellInit: ShellInit,
+        shellController: ShellController,
+        shellCommandHandler: ShellCommandHandler,
+    ) : this(
+        context,
+        shellInit,
+        shellController,
+        shellCommandHandler,
+        IconProvider(context),
+        headerIconFactory = context.createIconFactory(R.dimen.desktop_mode_caption_icon_radius),
+        veilIconFactory = context.createIconFactory(R.dimen.desktop_mode_resize_veil_icon_size),
+    )
+
+    /**
+     * A map of task -> resources to prevent unnecessary binder calls and resource loading
+     * when multiple window decorations need the same resources, for example, the app name or icon
+     * used in the header and menu.
+     */
+    @VisibleForTesting
+    val taskToResourceCache = ConcurrentHashMap<Int, AppResources>()
+    /**
+     * Keeps track of existing tasks with a window decoration. Useful to verify that requests to
+     * get resources occur within the lifecycle of a window decoration, otherwise it'd be possible
+     * to load a tasks resources into memory without a future signal to clean up the resource.
+     * See [onWindowDecorClosed].
+     */
+    private val existingTasks = mutableSetOf<Int>()
+
+    @VisibleForTesting
+    lateinit var currentUserContext: Context
+
+    init {
+        shellInit.addInitCallback(this::onInit, this)
+    }
+
+    private fun onInit() {
+        shellCommandHandler.addDumpCallback(this::dump, this)
+        shellController.addUserChangeListener(object : UserChangeListener {
+            override fun onUserChanged(newUserId: Int, userContext: Context) {
+                currentUserContext = userContext
+                // No need to hold on to resources for tasks of another profile.
+                taskToResourceCache.clear()
+            }
+        })
+        currentUserContext = context.createContextAsUser(
+            UserHandle.of(ActivityManager.getCurrentUser()), /* flags= */ 0
+        )
+    }
+
+    /** Returns the user readable name for this task. */
+    @ShellBackgroundThread
+    fun getName(taskInfo: RunningTaskInfo): CharSequence {
+        checkWindowDecorExists(taskInfo)
+        val cachedResources = taskToResourceCache[taskInfo.taskId]
+        if (cachedResources != null) {
+            return cachedResources.appName
+        }
+        val resources = loadAppResources(taskInfo)
+        taskToResourceCache[taskInfo.taskId] = resources
+        return resources.appName
+    }
+
+    /** Returns the icon for use by the app header and menus for this task. */
+    @ShellBackgroundThread
+    fun getHeaderIcon(taskInfo: RunningTaskInfo): Bitmap {
+        checkWindowDecorExists(taskInfo)
+        val cachedResources = taskToResourceCache[taskInfo.taskId]
+        if (cachedResources != null) {
+            return cachedResources.appIcon
+        }
+        val resources = loadAppResources(taskInfo)
+        taskToResourceCache[taskInfo.taskId] = resources
+        return resources.appIcon
+    }
+
+    /** Returns the icon for use by the resize veil for this task. */
+    @ShellBackgroundThread
+    fun getVeilIcon(taskInfo: RunningTaskInfo): Bitmap {
+        checkWindowDecorExists(taskInfo)
+        val cachedResources = taskToResourceCache[taskInfo.taskId]
+        if (cachedResources != null) {
+            return cachedResources.veilIcon
+        }
+        val resources = loadAppResources(taskInfo)
+        taskToResourceCache[taskInfo.taskId] = resources
+        return resources.veilIcon
+    }
+
+    /** Called when a window decoration for this task is created. */
+    fun onWindowDecorCreated(taskInfo: RunningTaskInfo) {
+        existingTasks.add(taskInfo.taskId)
+    }
+
+    /** Called when a window decoration for this task is closed. */
+    fun onWindowDecorClosed(taskInfo: RunningTaskInfo) {
+        existingTasks.remove(taskInfo.taskId)
+        taskToResourceCache.remove(taskInfo.taskId)
+    }
+
+    private fun checkWindowDecorExists(taskInfo: RunningTaskInfo) {
+        check(existingTasks.contains(taskInfo.taskId)) {
+            "Attempt to obtain resource for non-existent decoration"
+        }
+    }
+
+    private fun loadAppResources(taskInfo: RunningTaskInfo): AppResources {
+        Trace.beginSection("$TAG#loadAppResources")
+        val pm = currentUserContext.packageManager
+        val activityInfo = getActivityInfo(taskInfo, pm)
+        val appName = pm.getApplicationLabel(activityInfo.applicationInfo)
+        val appIconDrawable = iconProvider.getIcon(activityInfo)
+        val badgedAppIconDrawable = pm.getUserBadgedIcon(appIconDrawable, taskInfo.userHandle())
+        val appIcon = headerIconFactory.createIconBitmap(badgedAppIconDrawable, /* scale= */ 1f)
+        val veilIcon = veilIconFactory.createScaledBitmap(appIconDrawable, MODE_DEFAULT)
+        Trace.endSection()
+        return AppResources(appName = appName, appIcon = appIcon, veilIcon = veilIcon)
+    }
+
+    private fun getActivityInfo(taskInfo: RunningTaskInfo, pm: PackageManager): ActivityInfo {
+        return pm.getActivityInfo(taskInfo.component(), /* flags= */ 0)
+    }
+
+    private fun RunningTaskInfo.component() = baseIntent.component!!
+
+    private fun RunningTaskInfo.userHandle() = UserHandle.of(userId)
+
+    data class AppResources(val appName: CharSequence, val appIcon: Bitmap, val veilIcon: Bitmap)
+
+    private fun dump(pw: PrintWriter, prefix: String) {
+        val innerPrefix = "$prefix  "
+        pw.println("${prefix}$TAG")
+        pw.println(innerPrefix + "appResourceCache=$taskToResourceCache")
+        pw.println(innerPrefix + "existingTasks=$existingTasks")
+    }
+
+    companion object {
+        private const val TAG = "AppResourceProvider"
+    }
+}
+
+/** Creates an icon factory with the provided [dimensions]. */
+fun Context.createIconFactory(@DimenRes dimensions: Int): BaseIconFactory {
+    val densityDpi = resources.displayMetrics.densityDpi
+    val iconSize = resources.getDimensionPixelSize(dimensions)
+    return BaseIconFactory(this, densityDpi, iconSize)
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/PooledWindowDecorViewHostSupplier.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/PooledWindowDecorViewHostSupplier.kt
index adb0ba6..47cfaee 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/PooledWindowDecorViewHostSupplier.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/PooledWindowDecorViewHostSupplier.kt
@@ -21,25 +21,57 @@
 import android.view.Display
 import android.view.SurfaceControl
 import com.android.wm.shell.shared.annotations.ShellMainThread
+import com.android.wm.shell.sysui.ShellInit
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
 
 /**
  * A [WindowDecorViewHostSupplier] backed by a pool to allow recycling view hosts which may be
  * expensive to recreate for each new or updated window decoration.
  *
- * Callers can obtain a [WindowDecorViewHost] using [acquire], which will return a pooled
- * object if available, or create a new instance and return it if needed. When finished using a
- * [WindowDecorViewHost], it must be released using [release] to allow it to be sent back
- * into the pool and reused later on.
+ * Callers can obtain a [WindowDecorViewHost] using [acquire], which will return a pooled object if
+ * available, or create a new instance and return it if needed. When finished using a
+ * [WindowDecorViewHost], it must be released using [release] to allow it to be sent back into the
+ * pool and reused later on.
+ *
+ * This class also supports pre-warming [ReusableWindowDecorViewHost] instances, which will be put
+ * into the pool immediately after creation.
  */
 class PooledWindowDecorViewHostSupplier(
+    private val context: Context,
     @ShellMainThread private val mainScope: CoroutineScope,
+    shellInit: ShellInit,
     maxPoolSize: Int,
+    private val preWarmSize: Int,
 ) : WindowDecorViewHostSupplier<WindowDecorViewHost> {
 
     private val pool: Pools.Pool<WindowDecorViewHost> = Pools.SynchronizedPool(maxPoolSize)
     private var nextDecorViewHostId = 0
 
+    init {
+        require(preWarmSize <= maxPoolSize) { "Pre-warm size should not exceed pool size" }
+        shellInit.addInitCallback(this::onShellInit, this)
+    }
+
+    private fun onShellInit() {
+        if (preWarmSize <= 0) {
+            return
+        }
+        preWarmViewHosts(preWarmSize)
+    }
+
+    private fun preWarmViewHosts(preWarmSize: Int) {
+        mainScope.launch {
+            // Applying isn't needed, as the surface was never actually shown.
+            val t = SurfaceControl.Transaction()
+            repeat(preWarmSize) {
+                val warmedViewHost = newInstance(context, context.display).apply { warmUp() }
+                // Put the warmed view host in the pool by releasing it.
+                release(warmedViewHost, t)
+            }
+        }
+    }
+
     override fun acquire(context: Context, display: Display): WindowDecorViewHost {
         val pooledViewHost = pool.acquire()
         if (pooledViewHost != null) {
@@ -64,7 +96,7 @@
             context = context,
             mainScope = mainScope,
             display = display,
-            id = nextDecorViewHostId++
+            id = nextDecorViewHostId++,
         )
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/ReusableWindowDecorViewHost.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/ReusableWindowDecorViewHost.kt
index bf0b118..da41e1b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/ReusableWindowDecorViewHost.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/ReusableWindowDecorViewHost.kt
@@ -17,11 +17,15 @@
 
 import android.content.Context
 import android.content.res.Configuration
+import android.graphics.PixelFormat
 import android.graphics.Region
 import android.view.Display
 import android.view.SurfaceControl
 import android.view.View
 import android.view.WindowManager
+import android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+import android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+import android.view.WindowManager.LayoutParams.TYPE_APPLICATION
 import android.widget.FrameLayout
 import androidx.tracing.Trace
 import com.android.internal.annotations.VisibleForTesting
@@ -35,6 +39,9 @@
  * 1) Replacing the root [View], meaning [WindowDecorViewHost.updateView] maybe be called with
  *    different [View] instances. This is useful when reusing [WindowDecorViewHost]s instances for
  *    vastly different view hierarchies, such as Desktop Windowing's App Handles and App Headers.
+ * 2) Pre-warming of the underlying [SurfaceControlViewHostAdapter]s. Useful because their creation
+ *    and first root view assignment are expensive, which is undesirable in latency-sensitive code
+ *    paths like during a shell transition.
  */
 class ReusableWindowDecorViewHost(
     private val context: Context,
@@ -44,7 +51,7 @@
     @VisibleForTesting
     val viewHostAdapter: SurfaceControlViewHostAdapter =
         SurfaceControlViewHostAdapter(context, display),
-) : WindowDecorViewHost {
+) : WindowDecorViewHost, Warmable {
     @VisibleForTesting val rootView = FrameLayout(context)
 
     private var currentUpdateJob: Job? = null
@@ -52,6 +59,30 @@
     override val surfaceControl: SurfaceControl
         get() = viewHostAdapter.rootSurface
 
+    override fun warmUp() {
+        if (viewHostAdapter.isInitialized()) {
+            // Already warmed up.
+            return
+        }
+        Trace.beginSection("$TAG#warmUp")
+        viewHostAdapter.prepareViewHost(context.resources.configuration, touchableRegion = null)
+        viewHostAdapter.updateView(
+            rootView,
+            WindowManager.LayoutParams(
+                    0 /* width*/,
+                    0 /* height */,
+                    TYPE_APPLICATION,
+                    FLAG_NOT_FOCUSABLE or FLAG_SPLIT_TOUCH,
+                    PixelFormat.TRANSPARENT,
+                )
+                .apply {
+                    setTitle("View root of $TAG#$id")
+                    setTrustedOverlay()
+                },
+        )
+        Trace.endSection()
+    }
+
     override fun updateView(
         view: View,
         attrs: WindowManager.LayoutParams,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/Warmable.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/Warmable.kt
new file mode 100644
index 0000000..2cb0f89
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/Warmable.kt
@@ -0,0 +1,23 @@
+/*
+ * 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.common.viewhost
+
+/**
+ * An interface for an object that can be warmed up before it's needed.
+ */
+interface Warmable {
+    fun warmUp()
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt
index 9db69d5..d72da3a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt
@@ -31,17 +31,23 @@
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.SyncTransactionQueue
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger
-import com.android.wm.shell.desktopmode.DesktopRepository
 import com.android.wm.shell.desktopmode.DesktopTasksController
 import com.android.wm.shell.desktopmode.DesktopUserRepositories
 import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
 import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler
+import com.android.wm.shell.shared.annotations.ShellBackgroundThread
+import com.android.wm.shell.shared.annotations.ShellMainThread
 import com.android.wm.shell.transition.Transitions
 import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration
+import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.MainCoroutineDispatcher
 
 /** Manages tiling for each displayId/userId independently. */
 class DesktopTilingDecorViewModel(
     private val context: Context,
+    @ShellMainThread private val mainDispatcher: MainCoroutineDispatcher,
+    @ShellBackgroundThread private val bgScope: CoroutineScope,
     private val displayController: DisplayController,
     private val rootTdaOrganizer: RootTaskDisplayAreaOrganizer,
     private val syncQueue: SyncTransactionQueue,
@@ -51,6 +57,7 @@
     private val returnToDragStartAnimator: ReturnToDragStartAnimator,
     private val desktopUserRepositories: DesktopUserRepositories,
     private val desktopModeEventLogger: DesktopModeEventLogger,
+    private val taskResourceLoader: WindowDecorTaskResourceLoader,
 ) : DisplayChangeController.OnDisplayChangingListener {
     @VisibleForTesting
     var tilingTransitionHandlerByDisplayId = SparseArray<DesktopTilingWindowDecoration>()
@@ -74,8 +81,11 @@
                     val newHandler =
                         DesktopTilingWindowDecoration(
                             context,
+                            mainDispatcher,
+                            bgScope,
                             syncQueue,
                             displayController,
+                            taskResourceLoader,
                             displayId,
                             rootTdaOrganizer,
                             transitions,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
index 7ceac52..6f23233 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
@@ -20,11 +20,9 @@
 import android.content.Context
 import android.content.res.Configuration
 import android.content.res.Resources
-import android.graphics.Bitmap
 import android.graphics.Rect
 import android.os.IBinder
 import android.os.UserHandle
-import android.util.Slog
 import android.view.MotionEvent
 import android.view.SurfaceControl
 import android.view.SurfaceControl.Transaction
@@ -37,8 +35,6 @@
 import android.window.WindowContainerTransaction
 import com.android.internal.annotations.VisibleForTesting
 import com.android.launcher3.icons.BaseIconFactory
-import com.android.launcher3.icons.BaseIconFactory.MODE_DEFAULT
-import com.android.launcher3.icons.IconProvider
 import com.android.wm.shell.R
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
 import com.android.wm.shell.ShellTaskOrganizer
@@ -47,11 +43,12 @@
 import com.android.wm.shell.common.SyncTransactionQueue
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
-import com.android.wm.shell.desktopmode.DesktopRepository
 import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition
 import com.android.wm.shell.desktopmode.DesktopUserRepositories
 import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
 import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler
+import com.android.wm.shell.shared.annotations.ShellBackgroundThread
+import com.android.wm.shell.shared.annotations.ShellMainThread
 import com.android.wm.shell.transition.Transitions
 import com.android.wm.shell.transition.Transitions.TRANSIT_MINIMIZE
 import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration
@@ -60,13 +57,19 @@
 import com.android.wm.shell.windowdecor.DragResizeWindowGeometry
 import com.android.wm.shell.windowdecor.DragResizeWindowGeometry.DisabledEdge.NONE
 import com.android.wm.shell.windowdecor.ResizeVeil
+import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader
 import com.android.wm.shell.windowdecor.extension.isFullscreen
 import java.util.function.Supplier
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.MainCoroutineDispatcher
 
 class DesktopTilingWindowDecoration(
     private var context: Context,
+    @ShellMainThread private val mainDispatcher: MainCoroutineDispatcher,
+    @ShellBackgroundThread private val bgScope: CoroutineScope,
     private val syncQueue: SyncTransactionQueue,
     private val displayController: DisplayController,
+    private val taskResourceLoader: WindowDecorTaskResourceLoader,
     private val displayId: Int,
     private val rootTdaOrganizer: RootTaskDisplayAreaOrganizer,
     private val transitions: Transitions,
@@ -110,6 +113,9 @@
                 context,
                 destinationBounds,
                 displayController,
+                taskResourceLoader,
+                mainDispatcher,
+                bgScope,
                 transactionSupplier,
             )
         val isFirstTiledApp = leftTaskResizingHelper == null && rightTaskResizingHelper == null
@@ -408,11 +414,13 @@
         val context: Context,
         val bounds: Rect,
         val displayController: DisplayController,
+        private val taskResourceLoader: WindowDecorTaskResourceLoader,
+        @ShellMainThread val mainDispatcher: MainCoroutineDispatcher,
+        @ShellBackgroundThread val bgScope: CoroutineScope,
         val transactionSupplier: Supplier<Transaction>,
     ) {
         var isInitialised = false
         var newBounds = Rect(bounds)
-        private lateinit var resizeVeilBitmap: Bitmap
         private lateinit var resizeVeil: ResizeVeil
         private val displayContext = displayController.getDisplayContext(taskInfo.displayId)
         private val userContext =
@@ -426,26 +434,14 @@
         }
 
         private fun initVeil() {
-            val baseActivity = taskInfo.baseActivity
-            if (baseActivity == null) {
-                Slog.e(TAG, "Base activity component not found in task")
-                return
-            }
-            val resizeVeilIconFactory =
-                displayContext?.let {
-                    createIconFactory(displayContext, R.dimen.desktop_mode_resize_veil_icon_size)
-                } ?: return
-            val pm = userContext.getPackageManager()
-            val activityInfo = pm.getActivityInfo(baseActivity, 0 /* flags */)
-            val provider = IconProvider(displayContext)
-            val appIconDrawable = provider.getIcon(activityInfo)
-            resizeVeilBitmap =
-                resizeVeilIconFactory.createScaledBitmap(appIconDrawable, MODE_DEFAULT)
+            displayContext ?: return
             resizeVeil =
                 ResizeVeil(
                     context = displayContext,
                     displayController = displayController,
-                    appIcon = resizeVeilBitmap,
+                    taskResourceLoader = taskResourceLoader,
+                    mainDispatcher = mainDispatcher,
+                    bgScope = bgScope,
                     parentSurface = desktopModeWindowDecoration.getLeash(),
                     surfaceControlTransactionSupplier = transactionSupplier,
                     taskInfo = taskInfo,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
index d943918..dc4fa37 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
@@ -40,12 +40,12 @@
 import androidx.core.content.withStyledAttributes
 import androidx.core.view.isGone
 import androidx.core.view.isVisible
-import com.android.internal.R.attr.materialColorOnSecondaryContainer
-import com.android.internal.R.attr.materialColorOnSurface
-import com.android.internal.R.attr.materialColorSecondaryContainer
-import com.android.internal.R.attr.materialColorSurfaceContainerHigh
-import com.android.internal.R.attr.materialColorSurfaceContainerLow
-import com.android.internal.R.attr.materialColorSurfaceDim
+import com.android.internal.R.color.materialColorOnSecondaryContainer
+import com.android.internal.R.color.materialColorOnSurface
+import com.android.internal.R.color.materialColorSecondaryContainer
+import com.android.internal.R.color.materialColorSurfaceContainerHigh
+import com.android.internal.R.color.materialColorSurfaceContainerLow
+import com.android.internal.R.color.materialColorSurfaceDim
 import com.android.window.flags.Flags
 import com.android.window.flags.Flags.enableMinimizeButton
 import com.android.wm.shell.R
@@ -72,14 +72,12 @@
         onCaptionButtonClickListener: View.OnClickListener,
         private val onLongClickListener: OnLongClickListener,
         onCaptionGenericMotionListener: View.OnGenericMotionListener,
-        appName: CharSequence,
-        appIconBitmap: Bitmap,
         onMaximizeHoverAnimationFinishedListener: () -> Unit
 ) : WindowDecorationViewHolder<AppHeaderViewHolder.HeaderData>(rootView) {
 
     data class HeaderData(
         val taskInfo: RunningTaskInfo,
-        val isRequestingImmersive: Boolean,
+        val isTaskMaximized: Boolean,
         val inFullImmersiveState: Boolean,
         val hasGlobalFocus: Boolean,
         val enableMaximizeLongClick: Boolean,
@@ -154,8 +152,6 @@
         closeWindowButton.setOnTouchListener(onCaptionTouchListener)
         minimizeWindowButton.setOnClickListener(onCaptionButtonClickListener)
         minimizeWindowButton.setOnTouchListener(onCaptionTouchListener)
-        appNameTextView.text = appName
-        appIconImageView.setImageBitmap(appIconBitmap)
         maximizeButtonView.onHoverAnimationFinishedListener =
                 onMaximizeHoverAnimationFinishedListener
     }
@@ -163,16 +159,26 @@
     override fun bindData(data: HeaderData) {
         bindData(
             data.taskInfo,
-            data.isRequestingImmersive,
+            data.isTaskMaximized,
             data.inFullImmersiveState,
             data.hasGlobalFocus,
             data.enableMaximizeLongClick
         )
     }
 
+    /** Sets the app's name in the header. */
+    fun setAppName(name: CharSequence) {
+        appNameTextView.text = name
+    }
+
+    /** Sets the app's icon in the header. */
+    fun setAppIcon(icon: Bitmap) {
+        appIconImageView.setImageBitmap(icon)
+    }
+
     private fun bindData(
         taskInfo: RunningTaskInfo,
-        isRequestingImmersive: Boolean,
+        isTaskMaximized: Boolean,
         inFullImmersiveState: Boolean,
         hasGlobalFocus: Boolean,
         enableMaximizeLongClick: Boolean,
@@ -180,7 +186,7 @@
         if (DesktopModeFlags.ENABLE_THEMED_APP_HEADERS.isTrue()) {
             bindDataWithThemedHeaders(
                 taskInfo,
-                isRequestingImmersive,
+                isTaskMaximized,
                 inFullImmersiveState,
                 hasGlobalFocus,
                 enableMaximizeLongClick,
@@ -225,7 +231,7 @@
 
     private fun bindDataWithThemedHeaders(
         taskInfo: RunningTaskInfo,
-        requestingImmersive: Boolean,
+        isTaskMaximized: Boolean,
         inFullImmersiveState: Boolean,
         hasGlobalFocus: Boolean,
         enableMaximizeLongClick: Boolean,
@@ -283,7 +289,7 @@
                     drawableInsets = maximizeDrawableInsets
                 )
             )
-            setIcon(getMaximizeButtonIcon(requestingImmersive, inFullImmersiveState))
+            setIcon(getMaximizeButtonIcon(isTaskMaximized, inFullImmersiveState))
         }
         // Close button.
         closeWindowButton.apply {
@@ -358,34 +364,19 @@
 
     @DrawableRes
     private fun getMaximizeButtonIcon(
-        requestingImmersive: Boolean,
+        isTaskMaximized: Boolean,
         inFullImmersiveState: Boolean
     ): Int = when {
-        shouldShowEnterFullImmersiveIcon(requestingImmersive, inFullImmersiveState) -> {
-            R.drawable.decor_desktop_mode_immersive_button_dark
-        }
-        shouldShowExitFullImmersiveIcon(requestingImmersive, inFullImmersiveState) -> {
-            R.drawable.decor_desktop_mode_immersive_exit_button_dark
+        shouldShowExitFullImmersiveOrMaximizeIcon(isTaskMaximized, inFullImmersiveState) -> {
+            R.drawable.decor_desktop_mode_immersive_or_maximize_exit_button_dark
         }
         else -> R.drawable.decor_desktop_mode_maximize_button_dark
     }
 
-    private fun shouldShowEnterFullImmersiveIcon(
-        requestingImmersive: Boolean,
+    private fun shouldShowExitFullImmersiveOrMaximizeIcon(
+        isTaskMaximized: Boolean,
         inFullImmersiveState: Boolean
-    ): Boolean = Flags.enableFullyImmersiveInDesktop()
-            && requestingImmersive && !inFullImmersiveState
-
-    private fun shouldShowExitFullImmersiveIcon(
-        requestingImmersive: Boolean,
-        inFullImmersiveState: Boolean
-    ): Boolean = isInFullImmersiveStateAndRequesting(requestingImmersive, inFullImmersiveState)
-
-    private fun isInFullImmersiveStateAndRequesting(
-        requestingImmersive: Boolean,
-        inFullImmersiveState: Boolean
-    ): Boolean = Flags.enableFullyImmersiveInDesktop()
-            && requestingImmersive && inFullImmersiveState
+    ): Boolean = (Flags.enableFullyImmersiveInDesktop() && inFullImmersiveState) || isTaskMaximized
 
     private fun getHeaderStyle(header: Header): HeaderStyle {
         return HeaderStyle(
@@ -595,33 +586,31 @@
 
     @ColorInt
     private fun getAppNameAndButtonColor(taskInfo: RunningTaskInfo, hasGlobalFocus: Boolean): Int {
-        val materialColorAttr = when {
+        val materialColor = context.getColor(when {
             taskInfo.isTransparentCaptionBarAppearance &&
                     taskInfo.isLightCaptionBarAppearance -> materialColorOnSecondaryContainer
             taskInfo.isTransparentCaptionBarAppearance &&
                     !taskInfo.isLightCaptionBarAppearance -> materialColorOnSurface
             isDarkMode() -> materialColorOnSurface
             else -> materialColorOnSecondaryContainer
-        }
+        })
         val appDetailsOpacity = when {
             isDarkMode() && !hasGlobalFocus -> DARK_THEME_UNFOCUSED_OPACITY
             !isDarkMode() && !hasGlobalFocus -> LIGHT_THEME_UNFOCUSED_OPACITY
             else -> FOCUSED_OPACITY
         }
-        context.withStyledAttributes(null, intArrayOf(materialColorAttr), 0, 0) {
-            val color = getColor(0, 0)
-            return if (appDetailsOpacity == FOCUSED_OPACITY) {
-                color
-            } else {
-                Color.argb(
-                    appDetailsOpacity,
-                    Color.red(color),
-                    Color.green(color),
-                    Color.blue(color)
-                )
-            }
+
+
+        return if (appDetailsOpacity == FOCUSED_OPACITY) {
+            materialColor
+        } else {
+            Color.argb(
+                appDetailsOpacity,
+                Color.red(materialColor),
+                Color.green(materialColor),
+                Color.blue(materialColor)
+            )
         }
-        return 0
     }
 
     private fun isDarkMode(): Boolean {
@@ -645,8 +634,6 @@
             onCaptionButtonClickListener: View.OnClickListener,
             onLongClickListener: OnLongClickListener,
             onCaptionGenericMotionListener: View.OnGenericMotionListener,
-            appName: CharSequence,
-            appIconBitmap: Bitmap,
             onMaximizeHoverAnimationFinishedListener: () -> Unit,
         ): AppHeaderViewHolder = AppHeaderViewHolder(
             rootView,
@@ -654,8 +641,6 @@
             onCaptionButtonClickListener,
             onLongClickListener,
             onCaptionGenericMotionListener,
-            appName,
-            appIconBitmap,
             onMaximizeHoverAnimationFinishedListener,
         )
     }
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 a2afd2c..47ee7bb 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
@@ -718,7 +718,7 @@
         tInfo = createTransitionInfo(TRANSIT_PREPARE_BACK_NAVIGATION, open);
         callback = mock(Transitions.TransitionFinishCallback.class);
         mBackTransitionHandler.startAnimation(mockBinder, tInfo, st, ft, callback);
-        verify(mBackTransitionHandler).handlePrepareTransition(
+        verify(mBackTransitionHandler).handlePrepareTransition(eq(mockBinder),
                 eq(tInfo), eq(st), eq(ft), eq(callback));
         mBackTransitionHandler.mCloseTransitionRequested = true;
         TransitionInfo tInfo2 = createTransitionInfo(TRANSIT_CLOSE, close);
@@ -750,7 +750,7 @@
                 null /* remoteTransition */);
         mBackTransitionHandler.handleRequest(mockBinder, requestInfo);
         mBackTransitionHandler.startAnimation(mockBinder, tInfo, st, ft, callback);
-        verify(mBackTransitionHandler).handlePrepareTransition(
+        verify(mBackTransitionHandler).handlePrepareTransition(eq(mockBinder),
                 eq(tInfo), eq(st), eq(ft), eq(callback));
 
         mBackTransitionHandler.onAnimationFinished();
@@ -801,7 +801,7 @@
         canHandle = mBackTransitionHandler.startAnimation(mockBinder,
                 prepareInfo, st, ft, callback2);
         assertTrue("Handle prepare transition" , canHandle);
-        verify(mBackTransitionHandler).handlePrepareTransition(
+        verify(mBackTransitionHandler).handlePrepareTransition(eq(mockBinder),
                 eq(prepareInfo), eq(st), eq(ft), eq(callback2));
         final TransitionInfo closeInfo = createTransitionInfo(TRANSIT_CLOSE, close);
         Transitions.TransitionFinishCallback mergeCallback =
@@ -819,7 +819,7 @@
         canHandle = mBackTransitionHandler.startAnimation(
                 mockBinder, prepareInfo, st, ft, callback3);
         assertTrue("Handle prepare transition" , canHandle);
-        verify(mBackTransitionHandler).handlePrepareTransition(
+        verify(mBackTransitionHandler).handlePrepareTransition(eq(mockBinder),
                 eq(prepareInfo), eq(st), eq(ft), eq(callback3));
         final TransitionInfo.Change open2 = createAppChange(
                 openTaskId2, TRANSIT_OPEN, FLAG_MOVED_TO_TOP);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleViewTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleViewTest.java
index 329a109..bf03834 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleViewTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleViewTest.java
@@ -15,9 +15,12 @@
  */
 package com.android.wm.shell.bubbles.bar;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 
+import android.graphics.Color;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
@@ -61,4 +64,18 @@
         assertEquals(handleColor,
                 ContextCompat.getColor(mContext, R.color.bubble_bar_expanded_view_handle_light));
     }
+
+    @Test
+    public void testSetHandleInitialColor_beforeUpdateHandleColor_updatesColor() {
+        mHandleView.setHandleInitialColor(Color.RED);
+        assertThat(mHandleView.getHandleColor()).isEqualTo(Color.RED);
+    }
+
+    @Test
+    public void testSetHandleInitialColor_afterUpdateHandleColor_doesNotUpdateColor() {
+        mHandleView.updateHandleColor(/* isRegionDark= */ true, /* animated= */ false);
+        mHandleView.setHandleInitialColor(Color.RED);
+        assertThat(mHandleView.getHandleColor()).isEqualTo(
+                ContextCompat.getColor(mContext, R.color.bubble_bar_expanded_view_handle_light));
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/OWNERS b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/OWNERS
index 5b05af9..3a017f3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/OWNERS
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/OWNERS
@@ -1,2 +1,8 @@
 # Bug component: 970984
-# includes OWNERS from parent directories
\ No newline at end of file
+# includes OWNERS from parent directories
+
+mariiasand@google.com
+mcarli@google.com
+minagranic@google.com
+gracielawputri@google.com
+eevlachavas@google.com
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxControllerRobotTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxControllerRobotTest.kt
index 95a0c82..88cc981 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxControllerRobotTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxControllerRobotTest.kt
@@ -16,10 +16,8 @@
 
 package com.android.wm.shell.compatui.letterbox
 
-import android.content.Context
 import android.graphics.Rect
 import android.view.SurfaceControl
-import com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn
 import com.android.wm.shell.compatui.letterbox.LetterboxMatchers.asAnyMode
 import org.mockito.kotlin.any
 import org.mockito.kotlin.clearInvocations
@@ -31,10 +29,7 @@
 /**
  * Robot to test [LetterboxController] implementations.
  */
-open class LetterboxControllerRobotTest(
-    ctx: Context,
-    controllerBuilder: (LetterboxSurfaceBuilder) -> LetterboxController
-) {
+abstract class LetterboxControllerRobotTest {
 
     companion object {
         @JvmStatic
@@ -44,21 +39,21 @@
         private val TASK_ID = 20
     }
 
-    private val letterboxConfiguration: LetterboxConfiguration
-    private val surfaceBuilder: LetterboxSurfaceBuilder
-    private val letterboxController: LetterboxController
-    private val transaction: SurfaceControl.Transaction
-    private val parentLeash: SurfaceControl
+    lateinit var letterboxController: LetterboxController
+    val transaction: SurfaceControl.Transaction
+    val parentLeash: SurfaceControl
 
     init {
-        letterboxConfiguration = LetterboxConfiguration(ctx)
-        surfaceBuilder = LetterboxSurfaceBuilder(letterboxConfiguration)
-        letterboxController = controllerBuilder(surfaceBuilder)
         transaction = getTransactionMock()
         parentLeash = mock<SurfaceControl>()
-        spyOn(surfaceBuilder)
     }
 
+    fun initController() {
+        letterboxController = buildController()
+    }
+
+    abstract fun buildController(): LetterboxController
+
     fun sendCreateSurfaceRequest(
         displayId: Int = DISPLAY_ID,
         taskId: Int = TASK_ID
@@ -102,16 +97,6 @@
         letterboxController.dump()
     }
 
-    fun checkSurfaceBuilderInvoked(times: Int = 1, name: String = "", callSite: String = "") {
-        verify(surfaceBuilder, times(times)).createSurface(
-            eq(transaction),
-            eq(parentLeash),
-            name.asAnyMode(),
-            callSite.asAnyMode(),
-            any()
-        )
-    }
-
     fun checkTransactionRemovedInvoked(times: Int = 1) {
         verify(transaction, times(times)).remove(any())
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxUtilsTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxUtilsTest.kt
index 06b8052..dd4cb11 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxUtilsTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxUtilsTest.kt
@@ -16,12 +16,16 @@
 
 package com.android.wm.shell.compatui.letterbox
 
-import android.content.Context
 import android.graphics.Rect
 import android.testing.AndroidTestingRunner
+import android.view.SurfaceControl
 import androidx.test.filters.SmallTest
 import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.compatui.letterbox.LetterboxUtils.Maps.runOnItem
+import com.android.wm.shell.compatui.letterbox.LetterboxUtils.Transactions.moveAndCrop
 import java.util.function.Consumer
+import kotlin.test.assertEquals
+import kotlin.test.assertNull
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.kotlin.any
@@ -39,24 +43,14 @@
 @SmallTest
 class LetterboxUtilsTest : ShellTestCase() {
 
-    val firstLetterboxController = mock<LetterboxController>()
-    val secondLetterboxController = mock<LetterboxController>()
-    val thirdLetterboxController = mock<LetterboxController>()
-
-    private val letterboxControllerBuilder: (LetterboxSurfaceBuilder) -> LetterboxController =
-        { _ ->
-            firstLetterboxController.append(secondLetterboxController)
-                .append(thirdLetterboxController)
-        }
-
     @Test
     fun `Appended LetterboxController invoked creation on all the controllers`() {
         runTestScenario { r ->
             r.sendCreateSurfaceRequest()
 
-            r.verifyCreateSurfaceInvokedWithRequest(target = firstLetterboxController)
-            r.verifyCreateSurfaceInvokedWithRequest(target = secondLetterboxController)
-            r.verifyCreateSurfaceInvokedWithRequest(target = thirdLetterboxController)
+            r.verifyCreateSurfaceInvokedWithRequest(target = r.firstLetterboxController)
+            r.verifyCreateSurfaceInvokedWithRequest(target = r.secondLetterboxController)
+            r.verifyCreateSurfaceInvokedWithRequest(target = r.thirdLetterboxController)
         }
     }
 
@@ -64,9 +58,9 @@
     fun `Appended LetterboxController invoked destroy on all the controllers`() {
         runTestScenario { r ->
             r.sendDestroySurfaceRequest()
-            r.verifyDestroySurfaceInvokedWithRequest(target = firstLetterboxController)
-            r.verifyDestroySurfaceInvokedWithRequest(target = secondLetterboxController)
-            r.verifyDestroySurfaceInvokedWithRequest(target = thirdLetterboxController)
+            r.verifyDestroySurfaceInvokedWithRequest(target = r.firstLetterboxController)
+            r.verifyDestroySurfaceInvokedWithRequest(target = r.secondLetterboxController)
+            r.verifyDestroySurfaceInvokedWithRequest(target = r.thirdLetterboxController)
         }
     }
 
@@ -74,9 +68,9 @@
     fun `Appended LetterboxController invoked update visibility on all the controllers`() {
         runTestScenario { r ->
             r.sendUpdateSurfaceVisibilityRequest(visible = true)
-            r.verifyUpdateVisibilitySurfaceInvokedWithRequest(target = firstLetterboxController)
-            r.verifyUpdateVisibilitySurfaceInvokedWithRequest(target = secondLetterboxController)
-            r.verifyUpdateVisibilitySurfaceInvokedWithRequest(target = thirdLetterboxController)
+            r.verifyUpdateVisibilitySurfaceInvokedWithRequest(target = r.firstLetterboxController)
+            r.verifyUpdateVisibilitySurfaceInvokedWithRequest(target = r.secondLetterboxController)
+            r.verifyUpdateVisibilitySurfaceInvokedWithRequest(target = r.thirdLetterboxController)
         }
     }
 
@@ -84,9 +78,9 @@
     fun `Appended LetterboxController invoked update bounds on all the controllers`() {
         runTestScenario { r ->
             r.sendUpdateSurfaceBoundsRequest(taskBounds = Rect(), activityBounds = Rect())
-            r.verifyUpdateSurfaceBoundsInvokedWithRequest(target = firstLetterboxController)
-            r.verifyUpdateSurfaceBoundsInvokedWithRequest(target = secondLetterboxController)
-            r.verifyUpdateSurfaceBoundsInvokedWithRequest(target = thirdLetterboxController)
+            r.verifyUpdateSurfaceBoundsInvokedWithRequest(target = r.firstLetterboxController)
+            r.verifyUpdateSurfaceBoundsInvokedWithRequest(target = r.secondLetterboxController)
+            r.verifyUpdateSurfaceBoundsInvokedWithRequest(target = r.thirdLetterboxController)
         }
     }
 
@@ -94,9 +88,38 @@
     fun `Appended LetterboxController invoked update dump on all the controllers`() {
         runTestScenario { r ->
             r.invokeDump()
-            r.verifyDumpInvoked(target = firstLetterboxController)
-            r.verifyDumpInvoked(target = secondLetterboxController)
-            r.verifyDumpInvoked(target = thirdLetterboxController)
+            r.verifyDumpInvoked(target = r.firstLetterboxController)
+            r.verifyDumpInvoked(target = r.secondLetterboxController)
+            r.verifyDumpInvoked(target = r.thirdLetterboxController)
+        }
+    }
+
+    @Test
+    fun `runOnItem executes onFound when an item has been found for a key`() {
+        runTestScenario { r ->
+            r.initMap(1 to 2, 3 to 4)
+            r.runOnItem<Int>(1)
+            r.verifyOnItemInvoked(expectedItem = 2)
+            r.verifyOnMissingNotInvoked()
+        }
+    }
+
+    @Test
+    fun `runOnItem executes onMissing when an item has not been found for a key`() {
+        runTestScenario { r ->
+            r.initMap(1 to 2, 3 to 4)
+            r.runOnItem<Int>(8)
+            r.verifyOnItemNotInvoked()
+            r.verifyOnMissingInvoked(expectedKey = 8)
+        }
+    }
+
+    @Test
+    fun `moveAndCrop invoked Move and then Crop`() {
+        runTestScenario { r ->
+            r.invoke(Rect(1, 2, 51, 62))
+            r.verifySetPosition(expectedX = 1f, expectedY = 2f)
+            r.verifySetWindowCrop(expectedWidth = 50, expectedHeight = 60)
         }
     }
 
@@ -104,14 +127,21 @@
      * Runs a test scenario providing a Robot.
      */
     fun runTestScenario(consumer: Consumer<AppendLetterboxControllerRobotTest>) {
-        val robot = AppendLetterboxControllerRobotTest(mContext, letterboxControllerBuilder)
-        consumer.accept(robot)
+        consumer.accept(AppendLetterboxControllerRobotTest().apply { initController() })
     }
 
-    class AppendLetterboxControllerRobotTest(
-        ctx: Context,
-        builder: (LetterboxSurfaceBuilder) -> LetterboxController
-    ) : LetterboxControllerRobotTest(ctx, builder) {
+    class AppendLetterboxControllerRobotTest : LetterboxControllerRobotTest() {
+
+        val firstLetterboxController = mock<LetterboxController>()
+        val secondLetterboxController = mock<LetterboxController>()
+        val thirdLetterboxController = mock<LetterboxController>()
+
+        private var testableMap = mutableMapOf<Int, Int>()
+        private var onItemState: Int? = null
+        private var onMissingStateKey: Int? = null
+        private var onMissingStateMap: MutableMap<Int, Int>? = null
+
+        private val surface = SurfaceControl()
 
         fun verifyCreateSurfaceInvokedWithRequest(
             target: LetterboxController,
@@ -147,5 +177,50 @@
         ) {
             verify(target, times(times)).dump()
         }
+
+        fun initMap(vararg values: Pair<Int, Int>) = testableMap.putAll(values.toMap())
+
+        fun <T> runOnItem(key: Int) {
+            testableMap.runOnItem(key, onFound = { item ->
+                onItemState = item
+            }, onMissed = { k, m ->
+                onMissingStateKey = k
+                onMissingStateMap = m
+            })
+        }
+
+        fun verifyOnItemInvoked(expectedItem: Int) {
+            assertEquals(expectedItem, onItemState)
+        }
+
+        fun verifyOnItemNotInvoked() {
+            assertNull(onItemState)
+        }
+
+        fun verifyOnMissingInvoked(expectedKey: Int) {
+            assertEquals(expectedKey, onMissingStateKey)
+            assertEquals(onMissingStateMap, testableMap)
+        }
+
+        fun verifyOnMissingNotInvoked() {
+            assertNull(onMissingStateKey)
+            assertNull(onMissingStateMap)
+        }
+
+        fun invoke(rect: Rect) {
+            transaction.moveAndCrop(surface, rect)
+        }
+
+        fun verifySetPosition(expectedX: Float, expectedY: Float) {
+            verify(transaction).setPosition(surface, expectedX, expectedY)
+        }
+
+        fun verifySetWindowCrop(expectedWidth: Int, expectedHeight: Int) {
+            verify(transaction).setWindowCrop(surface, expectedWidth, expectedHeight)
+        }
+
+        override fun buildController(): LetterboxController =
+            firstLetterboxController.append(secondLetterboxController)
+                .append(thirdLetterboxController)
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/MixedLetterboxControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/MixedLetterboxControllerTest.kt
index e6bff4c..3b72ff1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/MixedLetterboxControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/MixedLetterboxControllerTest.kt
@@ -16,7 +16,6 @@
 
 package com.android.wm.shell.compatui.letterbox
 
-import android.content.Context
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
 import com.android.wm.shell.ShellTestCase
@@ -64,65 +63,48 @@
      * Runs a test scenario providing a Robot.
      */
     fun runTestScenario(consumer: Consumer<MixedLetterboxControllerRobotTest>) {
-        val robot = MixedLetterboxControllerRobotTest(mContext, ObjectToTestHolder())
-        consumer.accept(robot)
+        consumer.accept(MixedLetterboxControllerRobotTest().apply { initController() })
     }
 
-    class MixedLetterboxControllerRobotTest(
-        ctx: Context,
-        private val objectToTestHolder: ObjectToTestHolder
-    ) : LetterboxControllerRobotTest(ctx, objectToTestHolder.controllerBuilder) {
+    class MixedLetterboxControllerRobotTest : LetterboxControllerRobotTest() {
+        val singleLetterboxController: SingleSurfaceLetterboxController =
+            mock<SingleSurfaceLetterboxController>()
+        val multipleLetterboxController: MultiSurfaceLetterboxController =
+            mock<MultiSurfaceLetterboxController>()
+        val controllerStrategy: LetterboxControllerStrategy = mock<LetterboxControllerStrategy>()
 
         fun configureStrategyFor(letterboxMode: LetterboxMode) {
-            doReturn(letterboxMode).`when`(objectToTestHolder.controllerStrategy)
-                .getLetterboxImplementationMode()
+            doReturn(letterboxMode).`when`(controllerStrategy).getLetterboxImplementationMode()
         }
 
         fun checkCreateInvokedOnSingleController(times: Int = 1) {
-            verify(
-                objectToTestHolder.singleLetterboxController,
-                times(times)
-            ).createLetterboxSurface(any(), any(), any())
+            verify(singleLetterboxController, times(times)).createLetterboxSurface(
+                any(),
+                any(),
+                any()
+            )
         }
 
         fun checkCreateInvokedOnMultiController(times: Int = 1) {
-            verify(
-                objectToTestHolder.multipleLetterboxController,
-                times(times)
-            ).createLetterboxSurface(any(), any(), any())
+            verify(multipleLetterboxController, times(times)).createLetterboxSurface(
+                any(),
+                any(),
+                any()
+            )
         }
 
         fun checkDestroyInvokedOnSingleController(times: Int = 1) {
-            verify(
-                objectToTestHolder.singleLetterboxController,
-                times(times)
-            ).destroyLetterboxSurface(any(), any())
+            verify(singleLetterboxController, times(times)).destroyLetterboxSurface(any(), any())
         }
 
         fun checkDestroyInvokedOnMultiController(times: Int = 1) {
-            verify(
-                objectToTestHolder.multipleLetterboxController,
-                times(times)
-            ).destroyLetterboxSurface(any(), any())
+            verify(multipleLetterboxController, times(times)).destroyLetterboxSurface(any(), any())
         }
-    }
 
-    data class ObjectToTestHolder(
-        val singleLetterboxController: SingleSurfaceLetterboxController =
-        mock<SingleSurfaceLetterboxController>(),
-        val multipleLetterboxController: MultiSurfaceLetterboxController =
-        mock<MultiSurfaceLetterboxController>(),
-        val controllerStrategy: LetterboxControllerStrategy = mock<LetterboxControllerStrategy>()
-    ) {
-
-        private val mixedController =
-            MixedLetterboxController(
-                singleLetterboxController,
-                multipleLetterboxController,
-                controllerStrategy
-            )
-
-        val controllerBuilder: (LetterboxSurfaceBuilder) -> LetterboxController =
-            { _ -> mixedController }
+        override fun buildController(): LetterboxController = MixedLetterboxController(
+            singleLetterboxController,
+            multipleLetterboxController,
+            controllerStrategy
+        )
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/MultiSurfaceLetterboxControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/MultiSurfaceLetterboxControllerTest.kt
index 295d4ed..3fd837d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/MultiSurfaceLetterboxControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/MultiSurfaceLetterboxControllerTest.kt
@@ -16,13 +16,20 @@
 
 package com.android.wm.shell.compatui.letterbox
 
+import android.content.Context
 import android.graphics.Rect
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
+import com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn
 import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.compatui.letterbox.LetterboxMatchers.asAnyMode
 import java.util.function.Consumer
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
 
 /**
  * Tests for [MultiSurfaceLetterboxController].
@@ -147,9 +154,33 @@
     /**
      * Runs a test scenario providing a Robot.
      */
-    fun runTestScenario(consumer: Consumer<LetterboxControllerRobotTest>) {
-        val robot =
-            LetterboxControllerRobotTest(mContext, { sb -> MultiSurfaceLetterboxController(sb) })
-        consumer.accept(robot)
+    fun runTestScenario(consumer: Consumer<MultiLetterboxControllerRobotTest>) {
+        consumer.accept(MultiLetterboxControllerRobotTest(mContext).apply { initController() })
+    }
+
+    class MultiLetterboxControllerRobotTest(context: Context) :
+        LetterboxControllerRobotTest() {
+
+        private val letterboxConfiguration: LetterboxConfiguration
+        private val surfaceBuilder: LetterboxSurfaceBuilder
+
+        init {
+            letterboxConfiguration = LetterboxConfiguration(context)
+            surfaceBuilder = LetterboxSurfaceBuilder(letterboxConfiguration)
+            spyOn(surfaceBuilder)
+        }
+
+        override fun buildController(): LetterboxController =
+            MultiSurfaceLetterboxController(surfaceBuilder)
+
+        fun checkSurfaceBuilderInvoked(times: Int = 1, name: String = "", callSite: String = "") {
+            verify(surfaceBuilder, times(times)).createSurface(
+                eq(transaction),
+                eq(parentLeash),
+                name.asAnyMode(),
+                callSite.asAnyMode(),
+                any()
+            )
+        }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/SingleSurfaceLetterboxControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/SingleSurfaceLetterboxControllerTest.kt
index 125e700..e6ffe98 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/SingleSurfaceLetterboxControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/SingleSurfaceLetterboxControllerTest.kt
@@ -16,13 +16,20 @@
 
 package com.android.wm.shell.compatui.letterbox
 
+import android.content.Context
 import android.graphics.Rect
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
+import com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn
 import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.compatui.letterbox.LetterboxMatchers.asAnyMode
 import java.util.function.Consumer
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
 
 /**
  * Tests for [SingleSurfaceLetterboxController].
@@ -120,9 +127,33 @@
     /**
      * Runs a test scenario providing a Robot.
      */
-    fun runTestScenario(consumer: Consumer<LetterboxControllerRobotTest>) {
-        val robot =
-            LetterboxControllerRobotTest(mContext, { sb -> SingleSurfaceLetterboxController(sb) })
-        consumer.accept(robot)
+    fun runTestScenario(consumer: Consumer<SingleLetterboxControllerRobotTest>) {
+        consumer.accept(SingleLetterboxControllerRobotTest(mContext).apply { initController() })
+    }
+
+    class SingleLetterboxControllerRobotTest(context: Context) :
+        LetterboxControllerRobotTest() {
+
+        private val letterboxConfiguration: LetterboxConfiguration
+        private val surfaceBuilder: LetterboxSurfaceBuilder
+
+        init {
+            letterboxConfiguration = LetterboxConfiguration(context)
+            surfaceBuilder = LetterboxSurfaceBuilder(letterboxConfiguration)
+            spyOn(surfaceBuilder)
+        }
+
+        override fun buildController(): LetterboxController =
+            SingleSurfaceLetterboxController(surfaceBuilder)
+
+        fun checkSurfaceBuilderInvoked(times: Int = 1, name: String = "", callSite: String = "") {
+            verify(surfaceBuilder, times(times)).createSurface(
+                eq(transaction),
+                eq(parentLeash),
+                name.asAnyMode(),
+                callSite.asAnyMode(),
+                any()
+            )
+        }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
index 41a594a..4cc641c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
@@ -36,6 +36,7 @@
 import com.android.dx.mockito.inline.extended.StaticMockitoSession
 import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE
 import com.android.window.flags.Flags.FLAG_RESPECT_ORIENTATION_CHANGE_FOR_UNRESIZEABLE
+import com.android.wm.shell.sysui.ShellController
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.common.ShellExecutor
@@ -98,6 +99,7 @@
     @Mock lateinit var persistentRepository: DesktopPersistentRepository
     @Mock lateinit var repositoryInitializer: DesktopRepositoryInitializer
     @Mock lateinit var userManager: UserManager
+    @Mock lateinit var shellController: ShellController
 
     private lateinit var mockitoSession: StaticMockitoSession
     private lateinit var handler: DesktopActivityOrientationChangeHandler
@@ -123,6 +125,7 @@
             DesktopUserRepositories(
                 context,
                 shellInit,
+                shellController,
                 persistentRepository,
                 repositoryInitializer,
                 testScope,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
index db4c746..b87f200 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
@@ -42,6 +42,7 @@
 import com.android.wm.shell.TestShellExecutor
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.DisplayLayout
+import com.android.wm.shell.desktopmode.DesktopImmersiveController.Direction
 import com.android.wm.shell.desktopmode.DesktopImmersiveController.ExitReason.USER_INTERACTION
 import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
 import com.android.wm.shell.sysui.ShellInit
@@ -88,13 +89,15 @@
     @Before
     fun setUp() {
         userRepositories = DesktopUserRepositories(
-            context, ShellInit(TestShellExecutor()), mock(), mock(), mock(), mock()
+            context, ShellInit(TestShellExecutor()), mock(), mock(), mock(), mock(), mock()
         )
         whenever(mockDisplayController.getDisplayLayout(DEFAULT_DISPLAY))
             .thenReturn(mockDisplayLayout)
         whenever(mockDisplayLayout.getStableBounds(any())).thenAnswer { invocation ->
             (invocation.getArgument(0) as Rect).set(STABLE_BOUNDS)
         }
+        whenever(mockDisplayLayout.width()).thenReturn(DISPLAY_BOUNDS.width())
+        whenever(mockDisplayLayout.height()).thenReturn(DISPLAY_BOUNDS.height())
         controller = DesktopImmersiveController(
             shellInit = mock(),
             transitions = mockTransitions,
@@ -277,10 +280,12 @@
 
         controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
 
-        assertThat(controller.pendingExternalExitTransitions.any { exit ->
-            exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
-                    && exit.taskId == task.taskId
-        }).isTrue()
+        assertTransitionPending(
+            transition = transition,
+            taskId = task.taskId,
+            direction = Direction.EXIT,
+            animate = false
+        )
     }
 
     @Test
@@ -298,10 +303,12 @@
 
         controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
 
-        assertThat(controller.pendingExternalExitTransitions.any { exit ->
-            exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
-                    && exit.taskId == task.taskId
-        }).isFalse()
+        assertTransitionNotPending(
+            transition = transition,
+            taskId = task.taskId,
+            direction = Direction.EXIT,
+            animate = false
+        )
     }
 
     @Test
@@ -360,10 +367,12 @@
             reason = USER_INTERACTION,
         ).asExit()?.runOnTransitionStart?.invoke(transition)
 
-        assertThat(controller.pendingExternalExitTransitions.any { exit ->
-            exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
-                    && exit.taskId == task.taskId
-        }).isFalse()
+        assertTransitionNotPending(
+            transition = transition,
+            taskId = task.taskId,
+            animate = false,
+            direction = Direction.EXIT
+        )
     }
 
     @Test
@@ -416,10 +425,12 @@
         controller.exitImmersiveIfApplicable(wct, task, USER_INTERACTION)
             .asExit()?.runOnTransitionStart?.invoke(transition)
 
-        assertThat(controller.pendingExternalExitTransitions.any { exit ->
-            exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
-                    && exit.taskId == task.taskId
-        }).isTrue()
+        assertTransitionPending(
+            transition = transition,
+            taskId = task.taskId,
+            direction = Direction.EXIT,
+            animate = false
+        )
     }
 
     @Test
@@ -481,10 +492,12 @@
         )
         controller.onTransitionFinished(transition, aborted = false)
 
-        assertThat(controller.pendingExternalExitTransitions.any { exit ->
-            exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
-                    && exit.taskId == task.taskId
-        }).isFalse()
+        assertTransitionNotPending(
+            transition = transition,
+            taskId = task.taskId,
+            direction = Direction.EXIT,
+            animate = false
+        )
     }
 
     @Test
@@ -513,14 +526,18 @@
         controller.onTransitionMerged(transition, mergedToTransition)
         controller.onTransitionFinished(mergedToTransition, aborted = false)
 
-        assertThat(controller.pendingExternalExitTransitions.any { exit ->
-            exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
-                    && exit.taskId == task.taskId
-        }).isFalse()
-        assertThat(controller.pendingExternalExitTransitions.any { exit ->
-            exit.transition == mergedToTransition && exit.displayId == DEFAULT_DISPLAY
-                    && exit.taskId == task.taskId
-        }).isFalse()
+        assertTransitionNotPending(
+            transition = transition,
+            taskId = task.taskId,
+            animate = false,
+            direction = Direction.EXIT
+        )
+        assertTransitionNotPending(
+            transition = mergedToTransition,
+            taskId = task.taskId,
+            animate = false,
+            direction = Direction.EXIT
+        )
     }
 
     @Test
@@ -686,7 +703,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
-    fun externalAnimateResizeChange_doesNotCleanUpPendingTransitionState() {
+    fun externalAnimateResizeChange_doesNotRemovePendingTransition() {
         val task = createFreeformTask()
         val mockBinder = mock(IBinder::class.java)
         whenever(mockTransitions.startTransition(eq(TRANSIT_CHANGE), any(), eq(controller)))
@@ -709,12 +726,16 @@
         )
         animatorTestRule.advanceTimeBy(DesktopImmersiveController.FULL_IMMERSIVE_ANIM_DURATION_MS)
 
-        assertThat(controller.state).isNotNull()
+        assertTransitionPending(
+            transition = mockBinder,
+            taskId = task.taskId,
+            direction = Direction.EXIT
+        )
     }
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
-    fun startAnimation_missingChange_clearsState() {
+    fun startAnimation_missingChange_removesPendingTransition() {
         val task = createFreeformTask()
         val mockBinder = mock(IBinder::class.java)
         whenever(mockTransitions.startTransition(eq(TRANSIT_CHANGE), any(), eq(controller)))
@@ -735,7 +756,42 @@
             finishCallback = {}
         )
 
-        assertThat(controller.state).isNull()
+        assertTransitionNotPending(
+            transition = mockBinder,
+            taskId = task.taskId,
+            direction = Direction.ENTER
+        )
+    }
+
+    private fun assertTransitionPending(
+        transition: IBinder,
+        taskId: Int,
+        direction: Direction,
+        animate: Boolean = true,
+        displayId: Int = DEFAULT_DISPLAY
+    ) {
+        assertThat(controller.pendingImmersiveTransitions.any { pendingTransition ->
+            pendingTransition.transition == transition
+                    && pendingTransition.displayId == displayId
+                    && pendingTransition.taskId == taskId
+                    && pendingTransition.animate == animate
+                    && pendingTransition.direction == direction
+        }).isTrue()
+    }
+
+    private fun assertTransitionNotPending(
+        transition: IBinder,
+        taskId: Int,
+        direction: Direction,
+        animate: Boolean = true,
+        displayId: Int = DEFAULT_DISPLAY
+    ) {
+        assertThat(controller.pendingImmersiveTransitions.any { pendingTransition ->
+            pendingTransition.transition == transition
+                    && pendingTransition.displayId == displayId
+                    && pendingTransition.taskId == taskId
+                    && pendingTransition.direction == direction
+        }).isFalse()
     }
 
     private fun createTransitionInfo(
@@ -768,5 +824,6 @@
 
     companion object {
         private val STABLE_BOUNDS = Rect(0, 100, 2000, 1900)
+        private val DISPLAY_BOUNDS = Rect(0, 0, 2000, 2000)
     }
 }
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 6a4ad2e..0b12d22 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
@@ -81,6 +81,7 @@
 import com.android.dx.mockito.inline.extended.StaticMockitoSession
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.window.flags.Flags
+import com.android.window.flags.Flags.FLAG_ENABLE_PER_DISPLAY_DESKTOP_WALLPAPER_ACTIVITY
 import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE
 import com.android.window.flags.Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP
 import com.android.wm.shell.MockToken
@@ -276,6 +277,7 @@
       DesktopUserRepositories(
         context,
         shellInit,
+        shellController,
         persistentRepository,
         repositoryInitializer,
         testScope,
@@ -1217,14 +1219,40 @@
   }
 
   @Test
-  fun moveRunningTaskToDesktop_deviceSupported_taskIsMovedToDesktop() {
-    val task = setUpFullscreenTask()
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun moveBackgroundTaskToDesktop_remoteTransition_usesOneShotHandler() {
+    val transitionHandlerArgCaptor = ArgumentCaptor.forClass(TransitionHandler::class.java)
+    whenever(
+      transitions.startTransition(anyInt(), any(), transitionHandlerArgCaptor.capture())
+    ).thenReturn(Binder())
 
-    controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
+    val task = createTaskInfo(1)
+    whenever(shellTaskOrganizer.getRunningTaskInfo(anyInt())).thenReturn(null)
+    whenever(recentTasksController.findTaskInBackground(anyInt())).thenReturn(task)
+    controller.moveTaskToDesktop(
+      taskId = task.taskId,
+      transitionSource = UNKNOWN,
+      remoteTransition = RemoteTransition(spy(TestRemoteTransition())))
 
-    val wct = getLatestEnterDesktopWct()
-    assertThat(wct.changes[task.token.asBinder()]?.windowingMode).isEqualTo(WINDOWING_MODE_FREEFORM)
     verify(desktopModeEnterExitTransitionListener).onEnterDesktopModeTransitionStarted(FREEFORM_ANIMATION_DURATION)
+    assertIs<OneShotRemoteHandler>(transitionHandlerArgCaptor.value)
+  }
+
+
+  @Test
+  fun moveRunningTaskToDesktop_remoteTransition_usesOneShotHandler() {
+    val transitionHandlerArgCaptor = ArgumentCaptor.forClass(TransitionHandler::class.java)
+    whenever(
+      transitions.startTransition(anyInt(), any(), transitionHandlerArgCaptor.capture())
+    ).thenReturn(Binder())
+
+    controller.moveRunningTaskToDesktop(
+      task = setUpFullscreenTask(),
+      transitionSource = UNKNOWN,
+      remoteTransition = RemoteTransition(spy(TestRemoteTransition())))
+
+    verify(desktopModeEnterExitTransitionListener).onEnterDesktopModeTransitionStarted(FREEFORM_ANIMATION_DURATION)
+    assertIs<OneShotRemoteHandler>(transitionHandlerArgCaptor.value)
   }
 
   @Test
@@ -1598,6 +1626,30 @@
   }
 
   @Test
+  @EnableFlags(FLAG_ENABLE_PER_DISPLAY_DESKTOP_WALLPAPER_ACTIVITY)
+  fun moveToNextDisplay_removeWallpaper() {
+    // Set up two display ids
+    whenever(rootTaskDisplayAreaOrganizer.displayIds)
+      .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY))
+    // Create a mock for the target display area: second display
+    val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0)
+    whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY))
+      .thenReturn(secondDisplayArea)
+    // Add a task and a wallpaper
+    val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+    val wallpaperToken = MockToken().token()
+    taskRepository.wallpaperActivityToken = wallpaperToken
+
+    controller.moveToNextDisplay(task.taskId)
+
+    with(getLatestWct(type = TRANSIT_CHANGE)) {
+      val wallpaperChange = hierarchyOps.find { op -> op.container == wallpaperToken.asBinder() }
+      assertThat(wallpaperChange).isNotNull()
+      assertThat(wallpaperChange!!.type).isEqualTo(HIERARCHY_OP_TYPE_REMOVE_TASK)
+    }
+  }
+
+  @Test
   fun getTaskWindowingMode() {
     val fullscreenTask = setUpFullscreenTask()
     val freeformTask = setUpFreeformTask()
@@ -3062,20 +3114,21 @@
       .thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR)
 
     // Drag move the task to the top edge
+    val currentDragBounds = Rect(100, 50, 500, 1000)
     spyController.onDragPositioningMove(task, mockSurface, 200f, Rect(100, 200, 500, 1000))
     spyController.onDragPositioningEnd(
       task,
       mockSurface,
       Point(100, 50), /* position */
       PointF(200f, 300f), /* inputCoordinate */
-      Rect(100, 50, 500, 1000), /* currentDragBounds */
+      currentDragBounds,
       Rect(0, 50, 2000, 2000) /* validDragArea */,
       Rect() /* dragStartBounds */,
       motionEvent,
       desktopWindowDecoration)
 
     // Assert bounds set to stable bounds
-    val wct = getLatestToggleResizeDesktopTaskWct()
+    val wct = getLatestToggleResizeDesktopTaskWct(currentDragBounds)
     assertThat(findBoundsChange(wct, task)).isEqualTo(STABLE_BOUNDS)
     // Assert event is properly logged
     verify(desktopModeEventLogger, times(1)).logTaskResizingStarted(
@@ -3880,7 +3933,7 @@
 
   @Test
   fun shellController_registersUserChangeListener() {
-      verify(shellController, times(1)).addUserChangeListener(any())
+      verify(shellController, times(2)).addUserChangeListener(any())
   }
 
   @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
index 0712d58..39178cb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
@@ -42,6 +42,7 @@
 import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.sysui.ShellController
 import com.android.wm.shell.common.ShellExecutor
 import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
 import com.android.wm.shell.desktopmode.persistence.DesktopPersistentRepository
@@ -96,6 +97,7 @@
     @Mock lateinit var persistentRepository: DesktopPersistentRepository
     @Mock lateinit var repositoryInitializer: DesktopRepositoryInitializer
     @Mock lateinit var userManager: UserManager
+    @Mock lateinit var shellController: ShellController
 
     private lateinit var mockitoSession: StaticMockitoSession
     private lateinit var desktopTasksLimiter: DesktopTasksLimiter
@@ -117,6 +119,7 @@
             DesktopUserRepositories(
                 context,
                 shellInit,
+                shellController,
                 persistentRepository,
                 repositoryInitializer,
                 testScope,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopUserRepositoriesTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopUserRepositoriesTest.kt
index 5767df4..a2e939d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopUserRepositoriesTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopUserRepositoriesTest.kt
@@ -24,14 +24,15 @@
 import android.platform.test.flag.junit.SetFlagsRule
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
-import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
 import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
+import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
 import com.android.dx.mockito.inline.extended.StaticMockitoSession
 import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_HSUM
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.common.ShellExecutor
 import com.android.wm.shell.desktopmode.persistence.DesktopPersistentRepository
 import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer
+import com.android.wm.shell.sysui.ShellController
 import com.android.wm.shell.sysui.ShellInit
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
@@ -66,6 +67,7 @@
     private val persistentRepository = mock<DesktopPersistentRepository>()
     private val repositoryInitializer = mock<DesktopRepositoryInitializer>()
     private val userManager = mock<UserManager>()
+    private val shellController = mock<ShellController>()
 
     @Before
     fun setUp() {
@@ -86,8 +88,14 @@
         whenever(userManager.getProfiles(USER_ID_1)).thenReturn(profiles)
 
         userRepositories = DesktopUserRepositories(
-            context, shellInit, persistentRepository, repositoryInitializer, datastoreScope,
-                userManager)
+            context,
+            shellInit,
+            shellController,
+            persistentRepository,
+            repositoryInitializer,
+            datastoreScope,
+            userManager
+        )
     }
 
     @After
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerTest.kt
index 1c88a29..cdf064b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerTest.kt
@@ -27,6 +27,7 @@
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.common.ShellExecutor
 import com.android.wm.shell.desktopmode.DesktopUserRepositories
+import com.android.wm.shell.sysui.ShellController
 import com.android.wm.shell.sysui.ShellInit
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
@@ -64,6 +65,7 @@
     private val persistentRepository = mock<DesktopPersistentRepository>()
     private val userManager = mock<UserManager>()
     private val testExecutor = mock<ShellExecutor>()
+    private val shellController = mock<ShellController>()
 
     @Before
     fun setUp() {
@@ -74,7 +76,12 @@
             DesktopRepositoryInitializerImpl(context, persistentRepository, datastoreScope)
         desktopUserRepositories =
             DesktopUserRepositories(
-                context, shellInit, persistentRepository, repositoryInitializer, datastoreScope,
+                context,
+                shellInit,
+                shellController,
+                persistentRepository,
+                repositoryInitializer,
+                datastoreScope,
                 userManager
             )
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
index bb9703f..bca9c3f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
@@ -106,6 +106,7 @@
     @Mock RootTaskDisplayAreaOrganizer mRootTDAOrganizer;
     @Mock ShellExecutor mMainExecutor;
     @Mock Handler mMainHandler;
+    @Mock ShellExecutor mBgExecutor;
     @Mock DisplayController mDisplayController;
     @Mock DisplayImeController mDisplayImeController;
     @Mock DisplayInsetsController mDisplayInsetsController;
@@ -137,7 +138,8 @@
                 mDisplayInsetsController, mDragAndDropController, mTransitions, mTransactionPool,
                 mIconProvider, Optional.of(mRecentTasks), mLaunchAdjacentController,
                 Optional.of(mWindowDecorViewModel), Optional.of(mDesktopTasksController),
-                mStageCoordinator, mMultiInstanceHelper, mSplitState, mMainExecutor, mMainHandler));
+                mStageCoordinator, mMultiInstanceHelper, mSplitState, mMainExecutor, mMainHandler,
+                mBgExecutor));
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
index 1a2d60d..232ae07 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
@@ -78,14 +78,14 @@
                 StageTaskListener sideStage, DisplayController displayController,
                 DisplayImeController imeController, DisplayInsetsController insetsController,
                 SplitLayout splitLayout, Transitions transitions, TransactionPool transactionPool,
-                ShellExecutor mainExecutor, Handler mainHandler,
+                ShellExecutor mainExecutor, Handler mainHandler, ShellExecutor bgExecutor,
                 Optional<RecentTasksController> recentTasks,
                 LaunchAdjacentController launchAdjacentController,
                 Optional<WindowDecorViewModel> windowDecorViewModel, SplitState splitState) {
             super(context, displayId, syncQueue, taskOrganizer, mainStage,
                     sideStage, displayController, imeController, insetsController, splitLayout,
-                    transitions, transactionPool, mainExecutor, mainHandler, recentTasks,
-                    launchAdjacentController, windowDecorViewModel, splitState);
+                    transitions, transactionPool, mainExecutor, mainHandler, bgExecutor,
+                    recentTasks, launchAdjacentController, windowDecorViewModel, splitState);
 
             // Prepare root task for testing.
             mRootTask = new TestRunningTaskInfoBuilder().build();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index de77837..0d612c1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -111,6 +111,7 @@
     @Mock private WindowDecorViewModel mWindowDecorViewModel;
     @Mock private SplitState mSplitState;
     @Mock private ShellExecutor mMainExecutor;
+    @Mock private ShellExecutor mBgExecutor;
     @Mock private Handler mMainHandler;
     @Mock private LaunchAdjacentController mLaunchAdjacentController;
     @Mock private DefaultMixedHandler mMixedHandler;
@@ -136,16 +137,18 @@
         mSplitLayout = SplitTestUtils.createMockSplitLayout();
         mMainStage = spy(new StageTaskListener(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
                 StageTaskListener.StageListenerCallbacks.class), mSyncQueue,
-                mIconProvider, Optional.of(mWindowDecorViewModel), STAGE_TYPE_MAIN));
+                mIconProvider, mMainExecutor, mBgExecutor, Optional.of(mWindowDecorViewModel),
+                STAGE_TYPE_MAIN));
         mMainStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
         mSideStage = spy(new StageTaskListener(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
                 StageTaskListener.StageListenerCallbacks.class), mSyncQueue,
-                mIconProvider, Optional.of(mWindowDecorViewModel), STAGE_TYPE_SIDE));
+                mIconProvider, mMainExecutor, mBgExecutor, Optional.of(mWindowDecorViewModel),
+                STAGE_TYPE_SIDE));
         mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
         mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
                 mSyncQueue, mTaskOrganizer, mMainStage, mSideStage, mDisplayController,
                 mDisplayImeController, mDisplayInsetsController, mSplitLayout, mTransitions,
-                mTransactionPool, mMainExecutor, mMainHandler, Optional.empty(),
+                mTransactionPool, mMainExecutor, mMainHandler, mBgExecutor, Optional.empty(),
                 mLaunchAdjacentController, Optional.empty(), mSplitState);
         mStageCoordinator.setMixedHandler(mMixedHandler);
         mSplitScreenTransitions = mStageCoordinator.getSplitTransitions();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index 7afcce1..a6aeabd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -119,6 +119,8 @@
     private DefaultMixedHandler mDefaultMixedHandler;
     @Mock
     private SplitState mSplitState;
+    @Mock
+    private ShellExecutor mBgExecutor;
 
     private final Rect mBounds1 = new Rect(10, 20, 30, 40);
     private final Rect mBounds2 = new Rect(5, 10, 15, 20);
@@ -141,8 +143,8 @@
         mStageCoordinator = spy(new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
                 mTaskOrganizer, mMainStage, mSideStage, mDisplayController, mDisplayImeController,
                 mDisplayInsetsController, mSplitLayout, mTransitions, mTransactionPool,
-                mMainExecutor, mMainHandler, Optional.empty(), mLaunchAdjacentController,
-                Optional.empty(), mSplitState));
+                mMainExecutor, mMainHandler, mBgExecutor, Optional.empty(), 
+                mLaunchAdjacentController, Optional.empty(), mSplitState));
         mDividerLeash = new SurfaceControl.Builder().setName("fakeDivider").build();
 
         when(mSplitLayout.getTopLeftBounds()).thenReturn(mBounds1);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageOrderOperatorTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageOrderOperatorTests.kt
new file mode 100644
index 0000000..62b830d
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageOrderOperatorTests.kt
@@ -0,0 +1,151 @@
+/*
+ * 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.splitscreen
+
+import android.view.Display.DEFAULT_DISPLAY
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.launcher3.icons.IconProvider
+import com.android.wm.shell.Flags.enableFlexibleSplit
+import com.android.wm.shell.ShellTaskOrganizer
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.common.ShellExecutor
+import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_33_66
+import com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50
+import com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_66_33
+import com.android.wm.shell.splitscreen.StageTaskListener.StageListenerCallbacks
+import com.android.wm.shell.windowdecor.WindowDecorViewModel
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import java.util.Optional
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class StageOrderOperatorTests : ShellTestCase() {
+
+    @Mock
+    lateinit var mMainExecutor: ShellExecutor
+    @Mock
+    lateinit var mBgExecutor: ShellExecutor
+    @Mock
+    lateinit var mTaskOrganizer: ShellTaskOrganizer
+    @Mock
+    lateinit var mSyncQueue: SyncTransactionQueue
+    @Mock
+    lateinit var stageListenerCallbacks: StageListenerCallbacks
+    @Mock
+    lateinit var iconProvider: IconProvider
+    @Mock
+    lateinit var windowDecorViewModel: Optional<WindowDecorViewModel>
+
+    lateinit var stageOrderOperator: StageOrderOperator
+
+    @Before
+    fun setup() {
+        stageOrderOperator = StageOrderOperator(
+            context,
+            mTaskOrganizer,
+            DEFAULT_DISPLAY,
+            stageListenerCallbacks,
+            mSyncQueue,
+            iconProvider,
+            mMainExecutor,
+            mBgExecutor,
+            windowDecorViewModel,
+            )
+        assert(stageOrderOperator.activeStages.size == 0)
+    }
+
+    @Test
+    fun activeStages_2_2app_50_50_split() {
+        assumeTrue(enableFlexibleSplit())
+
+        stageOrderOperator.onEnteringSplit(SNAP_TO_2_50_50)
+        assert(stageOrderOperator.activeStages.size == 2)
+    }
+
+    @Test
+    fun activeStages_2_2app_33_66_split() {
+        assumeTrue(enableFlexibleSplit())
+
+        stageOrderOperator.onEnteringSplit(SNAP_TO_2_33_66)
+        assert(stageOrderOperator.activeStages.size == 2)
+    }
+
+    @Test
+    fun activeStages_2_2app_66_33_split() {
+        assumeTrue(enableFlexibleSplit())
+
+        stageOrderOperator.onEnteringSplit(SNAP_TO_2_66_33)
+        assert(stageOrderOperator.activeStages.size == 2)
+    }
+
+    @Test
+    fun activateSameCountStage_noOp() {
+        assumeTrue(enableFlexibleSplit())
+
+        stageOrderOperator.onEnteringSplit(SNAP_TO_2_66_33)
+        stageOrderOperator.onEnteringSplit(SNAP_TO_2_66_33)
+        assert(stageOrderOperator.activeStages.size == 2)
+    }
+
+    @Test
+    fun deactivate_emptyActiveStages() {
+        assumeTrue(enableFlexibleSplit())
+
+        stageOrderOperator.onEnteringSplit(SNAP_TO_2_66_33)
+        stageOrderOperator.onExitingSplit()
+        assert(stageOrderOperator.activeStages.isEmpty())
+    }
+
+    @Test
+    fun swapDividerPos_twoApps() {
+        assumeTrue(enableFlexibleSplit())
+
+        stageOrderOperator.onEnteringSplit(SNAP_TO_2_66_33)
+        val stageIndex0: StageTaskListener = stageOrderOperator.activeStages[0]
+        val stageIndex1: StageTaskListener = stageOrderOperator.activeStages[1]
+
+        stageOrderOperator.onDoubleTappedDivider()
+        val newStageIndex0: StageTaskListener = stageOrderOperator.activeStages[0]
+        val newStageIndex1: StageTaskListener = stageOrderOperator.activeStages[1]
+
+        assert(stageIndex0 == newStageIndex1)
+        assert(stageIndex1 == newStageIndex0)
+    }
+
+    @Test
+    fun swapDividerPos_twiceNoOp_twoApps() {
+        assumeTrue(enableFlexibleSplit())
+
+        stageOrderOperator.onEnteringSplit(SNAP_TO_2_66_33)
+        val stageIndex0: StageTaskListener = stageOrderOperator.activeStages[0]
+        val stageIndex1: StageTaskListener = stageOrderOperator.activeStages[1]
+
+        stageOrderOperator.onDoubleTappedDivider()
+        stageOrderOperator.onDoubleTappedDivider()
+        val newStageIndex0: StageTaskListener = stageOrderOperator.activeStages[0]
+        val newStageIndex1: StageTaskListener = stageOrderOperator.activeStages[1]
+
+        assert(stageIndex0 == newStageIndex0)
+        assert(stageIndex1 == newStageIndex1)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
index fe91440..effc6a7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
@@ -43,6 +43,7 @@
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestRunningTaskInfoBuilder;
+import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.windowdecor.WindowDecorViewModel;
 
@@ -73,6 +74,10 @@
     @Mock
     private SyncTransactionQueue mSyncQueue;
     @Mock
+    private ShellExecutor mMainExecutor;
+    @Mock
+    private ShellExecutor mBgExecutor;
+    @Mock
     private IconProvider mIconProvider;
     @Mock
     private WindowDecorViewModel mWindowDecorViewModel;
@@ -95,6 +100,8 @@
                 mCallbacks,
                 mSyncQueue,
                 mIconProvider,
+                mMainExecutor,
+                mBgExecutor,
                 Optional.of(mWindowDecorViewModel),
                 STAGE_TYPE_UNDEFINED);
         mRootTask = new TestRunningTaskInfoBuilder().build();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenuTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenuTest.kt
index e871711..cf6c3a5e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenuTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenuTest.kt
@@ -63,6 +63,7 @@
         userRepositories = DesktopUserRepositories(
             context = context,
             shellInit = ShellInit(TestShellExecutor()),
+            shellController = mock(),
             persistentRepository = mock(),
             repositoryInitializer = mock(),
             mainCoroutineScope = mock(),
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index 88f62d1..0214da4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -388,7 +388,7 @@
     }
 
     @Test
-    fun testOnDecorMaximizedOrRestored_togglesTaskSize() {
+    fun testOnDecorMaximizedOrRestored_togglesTaskSize_maximize() {
         val maxOrRestoreListenerCaptor = forClass(Function0::class.java)
                 as ArgumentCaptor<Function0<Unit>>
         val decor = createOpenTaskDecoration(
@@ -409,6 +409,52 @@
     }
 
     @Test
+    fun testOnDecorMaximizedOrRestored_togglesTaskSize_maximizeFromMaximizedSize() {
+        val maxOrRestoreListenerCaptor = forClass(Function0::class.java)
+                as ArgumentCaptor<Function0<Unit>>
+        val decor = createOpenTaskDecoration(
+            windowingMode = WINDOWING_MODE_FREEFORM,
+            onMaxOrRestoreListenerCaptor = maxOrRestoreListenerCaptor
+        )
+        val movedMaximizedBounds = Rect(STABLE_BOUNDS)
+        movedMaximizedBounds.offset(10, 10)
+        decor.mTaskInfo.configuration.windowConfiguration.bounds.set(movedMaximizedBounds)
+
+        maxOrRestoreListenerCaptor.value.invoke()
+
+        verify(mockDesktopTasksController).toggleDesktopTaskSize(
+            decor.mTaskInfo,
+            ToggleTaskSizeInteraction(
+                ToggleTaskSizeInteraction.Direction.MAXIMIZE,
+                ToggleTaskSizeInteraction.Source.MAXIMIZE_MENU_TO_MAXIMIZE,
+                InputMethod.UNKNOWN_INPUT_METHOD
+            )
+        )
+    }
+
+    @Test
+    fun testOnDecorMaximizedOrRestored_togglesTaskSize_restore() {
+        val maxOrRestoreListenerCaptor = forClass(Function0::class.java)
+                as ArgumentCaptor<Function0<Unit>>
+        val decor = createOpenTaskDecoration(
+            windowingMode = WINDOWING_MODE_FREEFORM,
+            onMaxOrRestoreListenerCaptor = maxOrRestoreListenerCaptor
+        )
+        decor.mTaskInfo.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS)
+
+        maxOrRestoreListenerCaptor.value.invoke()
+
+        verify(mockDesktopTasksController).toggleDesktopTaskSize(
+            decor.mTaskInfo,
+            ToggleTaskSizeInteraction(
+                ToggleTaskSizeInteraction.Direction.RESTORE,
+                ToggleTaskSizeInteraction.Source.MAXIMIZE_MENU_TO_RESTORE,
+                InputMethod.UNKNOWN_INPUT_METHOD
+            )
+        )
+    }
+
+    @Test
     fun testOnDecorMaximizedOrRestored_closesMenus() {
         val maxOrRestoreListenerCaptor = forClass(Function0::class.java)
                 as ArgumentCaptor<Function0<Unit>>
@@ -591,7 +637,8 @@
         verify(mockDesktopTasksController).moveTaskToDesktop(
             eq(decor.mTaskInfo.taskId),
             any(),
-            eq(DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON)
+            eq(DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON),
+            anyOrNull()
         )
     }
 
@@ -824,7 +871,7 @@
         )
 
         verify(mockDesktopTasksController, times(1))
-            .moveTaskToDesktop(any(), any(), any())
+            .moveTaskToDesktop(any(), any(), any(), anyOrNull())
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
index 6be234e..b5e8ceb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
@@ -74,6 +74,7 @@
 import com.android.wm.shell.util.StubTransaction
 import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel.DesktopModeKeyguardChangeListener
 import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel.DesktopModeOnInsetsChangedListener
+import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader
 import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost
 import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHostSupplier
 import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder
@@ -91,6 +92,8 @@
 import org.mockito.kotlin.whenever
 import java.util.Optional
 import java.util.function.Supplier
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.MainCoroutineDispatcher
 
 /**
  * Utility class for tests of [DesktopModeWindowDecorViewModel]
@@ -149,7 +152,6 @@
     protected val mockCaptionHandleRepository = mock<WindowDecorCaptionHandleRepository>()
     protected val mockDesktopRepository: DesktopRepository = mock<DesktopRepository>()
     protected val motionEvent = mock<MotionEvent>()
-    val displayController = mock<DisplayController>()
     val displayLayout = mock<DisplayLayout>()
     protected lateinit var spyContext: TestableContext
     private lateinit var desktopModeEventLogger: DesktopModeEventLogger
@@ -182,6 +184,8 @@
             testShellExecutor,
             mockMainHandler,
             mockMainChoreographer,
+            mock<MainCoroutineDispatcher>(),
+            mock<CoroutineScope>(),
             bgExecutor,
             shellInit,
             mockShellCommandHandler,
@@ -214,7 +218,8 @@
             mockTaskPositionerFactory,
             mockFocusTransitionObserver,
             desktopModeEventLogger,
-            mock<DesktopModeUiEventLogger>()
+            mock<DesktopModeUiEventLogger>(),
+            mock<WindowDecorTaskResourceLoader>()
         )
         desktopModeWindowDecorViewModel.setSplitScreenController(mockSplitScreenController)
         whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout)
@@ -255,7 +260,7 @@
             argumentCaptor<DesktopModeKeyguardChangeListener>()
         verify(mockShellController).addKeyguardChangeListener(keyguardChangedCaptor.capture())
         desktopModeOnKeyguardChangedListener = keyguardChangedCaptor.firstValue
-        whenever(displayController.getDisplayLayout(anyInt())).thenReturn(displayLayout)
+        whenever(mockDisplayController.getDisplayLayout(anyInt())).thenReturn(displayLayout)
         whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
             (i.arguments.first() as Rect).set(STABLE_BOUNDS)
         }
@@ -294,8 +299,9 @@
         val decoration = Mockito.mock(DesktopModeWindowDecoration::class.java)
         whenever(
             mockDesktopModeWindowDecorFactory.create(
-                any(), any(), any(), any(), any(), any(), eq(task), any(), any(), any(), any(),
-                any(), any(), any(), any(), any(), any(), any(), any(), any())
+                any(), any(), any(), any(), any(), any(), any(), eq(task), any(), any(), any(),
+                any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(),
+                any(), any())
         ).thenReturn(decoration)
         decoration.mTaskInfo = task
         whenever(decoration.user).thenReturn(mockUserHandle)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index 5d5d1f2..8a1a9b5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -20,6 +20,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.app.assist.AssistContent.EXTRA_SESSION_TRANSFER_WEB_URI;
 import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
 import static android.view.InsetsSource.FLAG_FORCE_CONSUMING;
 import static android.view.InsetsSource.FLAG_FORCE_CONSUMING_OPAQUE_CAPTION_BAR;
@@ -113,6 +114,7 @@
 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 import com.android.wm.shell.windowdecor.WindowDecoration.RelayoutParams;
+import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader;
 import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost;
 import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHostSupplier;
 import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder;
@@ -121,6 +123,9 @@
 import kotlin.jvm.functions.Function0;
 import kotlin.jvm.functions.Function1;
 
+import kotlinx.coroutines.CoroutineScope;
+import kotlinx.coroutines.MainCoroutineDispatcher;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -157,6 +162,7 @@
     private static final Uri TEST_URI1 = Uri.parse("https://www.google.com/");
     private static final Uri TEST_URI2 = Uri.parse("https://docs.google.com/");
     private static final Uri TEST_URI3 = Uri.parse("https://slides.google.com/");
+    private static final Uri TEST_URI4 = Uri.parse("https://calendar.google.com/");
 
     @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
 
@@ -171,6 +177,10 @@
     @Mock
     private Choreographer mMockChoreographer;
     @Mock
+    private MainCoroutineDispatcher mMockMainCoroutineDispatcher;
+    @Mock
+    private CoroutineScope mMockBgCoroutineScope;
+    @Mock
     private SyncTransactionQueue mMockSyncQueue;
     @Mock
     private AppHeaderViewHolder.Factory mMockAppHeaderViewHolderFactory;
@@ -222,6 +232,8 @@
     private DesktopModeEventLogger mDesktopModeEventLogger;
     @Mock
     private DesktopRepository mDesktopRepository;
+    @Mock
+    private WindowDecorTaskResourceLoader mMockTaskResourceLoader;
     @Captor
     private ArgumentCaptor<Function1<Boolean, Unit>> mOnMaxMenuHoverChangeListener;
     @Captor
@@ -232,6 +244,7 @@
     private StaticMockitoSession mMockitoSession;
     private TestableContext mTestableContext;
     private final ShellExecutor mBgExecutor = new TestShellExecutor();
+    private final ShellExecutor mMainExecutor = new TestShellExecutor();
     private final AssistContent mAssistContent = new AssistContent();
     private final Region mExclusionRegion = Region.obtain();
 
@@ -271,13 +284,13 @@
         final Display defaultDisplay = mock(Display.class);
         doReturn(defaultDisplay).when(mMockDisplayController).getDisplay(Display.DEFAULT_DISPLAY);
         doReturn(mInsetsState).when(mMockDisplayController).getInsetsState(anyInt());
-        when(mMockHandleMenuFactory.create(any(), any(), anyInt(), any(), any(), any(),
+        when(mMockHandleMenuFactory.create(any(), any(), any(), any(), any(), anyInt(), any(),
                 anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(),
                 any(), anyInt(), anyInt(), anyInt(), anyInt()))
                 .thenReturn(mMockHandleMenu);
         when(mMockMultiInstanceHelper.supportsMultiInstanceSplit(any())).thenReturn(false);
-        when(mMockAppHeaderViewHolderFactory.create(any(), any(), any(), any(), any(), any(), any(),
-                any())).thenReturn(mMockAppHeaderViewHolder);
+        when(mMockAppHeaderViewHolderFactory.create(any(), any(), any(), any(), any(), any()))
+                .thenReturn(mMockAppHeaderViewHolder);
         when(mMockDesktopUserRepositories.getCurrent()).thenReturn(mDesktopRepository);
         when(mMockDesktopUserRepositories.getProfile(anyInt())).thenReturn(mDesktopRepository);
         when(mMockWindowDecorViewHostSupplier.acquire(any(), eq(defaultDisplay)))
@@ -1322,11 +1335,11 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB)
-    public void capturedLink_handleMenuBrowserLinkSetToCapturedLinkIfValid() {
+    public void capturedLink_CapturedLinkUsedIfValidAndWebUriUnavailable() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
         final DesktopModeWindowDecoration decor = createWindowDecoration(
-                taskInfo, TEST_URI1 /* captured link */, TEST_URI2 /* web uri */,
-                TEST_URI3 /* generic link */);
+                taskInfo, TEST_URI1 /* captured link */, null /* web uri */,
+                null /* session transfer uri */, TEST_URI4 /* generic link */);
 
         // Verify handle menu's browser link set as captured link
         createHandleMenu(decor);
@@ -1339,7 +1352,7 @@
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
         final DesktopModeWindowDecoration decor = createWindowDecoration(
                 taskInfo, TEST_URI1 /* captured link */, null /* web uri */,
-                null /* generic link */);
+                null /* session transfer uri */, null /* generic link */);
         final ArgumentCaptor<Function1<Intent, Unit>> openInBrowserCaptor =
                 ArgumentCaptor.forClass(Function1.class);
 
@@ -1373,7 +1386,7 @@
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
         final DesktopModeWindowDecoration decor = createWindowDecoration(
                 taskInfo, TEST_URI1 /* captured link */, null /* web uri */,
-                null /* generic link */);
+                null /* session transfer uri */, null /* generic link */);
         final ArgumentCaptor<Function1<Intent, Unit>> openInBrowserCaptor =
                 ArgumentCaptor.forClass(Function1.class);
 
@@ -1406,7 +1419,7 @@
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
         final DesktopModeWindowDecoration decor = createWindowDecoration(
                 taskInfo, TEST_URI1 /* captured link */, null /* web uri */,
-                null /* generic link */);
+                null /* session transfer uri */, null /* generic link */);
         final ArgumentCaptor<Function1<Intent, Unit>> openInBrowserCaptor =
                 ArgumentCaptor.forClass(Function1.class);
         createHandleMenu(decor);
@@ -1432,11 +1445,23 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB)
-    public void webUriLink_webUriLinkUsedWhenCapturedLinkUnavailable() {
+    public void webUriLink_webUriLinkUsedWhenWhenAvailable() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
         final DesktopModeWindowDecoration decor = createWindowDecoration(
-                taskInfo, null /* captured link */, TEST_URI2 /* web uri */,
-                TEST_URI3 /* generic link */);
+                taskInfo, TEST_URI1 /* captured link */, TEST_URI2 /* web uri */,
+                TEST_URI3 /* session transfer uri */, TEST_URI4 /* generic link */);
+        // Verify handle menu's browser link set as web uri link when captured link is unavailable
+        createHandleMenu(decor);
+        verifyHandleMenuCreated(TEST_URI3);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB)
+    public void webUriLink_webUriLinkUsedWhenSessionTransferUriUnavailable() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+        final DesktopModeWindowDecoration decor = createWindowDecoration(
+                taskInfo, TEST_URI1 /* captured link */, TEST_URI2 /* web uri */,
+                null /* session transfer uri */, TEST_URI4 /* generic link */);
         // Verify handle menu's browser link set as web uri link when captured link is unavailable
         createHandleMenu(decor);
         verifyHandleMenuCreated(TEST_URI2);
@@ -1448,12 +1473,12 @@
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
         final DesktopModeWindowDecoration decor = createWindowDecoration(
                 taskInfo, null /* captured link */, null /* web uri */,
-                TEST_URI3 /* generic link */);
+                null /* session transfer uri */, TEST_URI4 /* generic link */);
 
         // Verify handle menu's browser link set as generic link when captured link and web uri link
         // are unavailable
         createHandleMenu(decor);
-        verifyHandleMenuCreated(TEST_URI3);
+        verifyHandleMenuCreated(TEST_URI4);
     }
 
     @Test
@@ -1637,7 +1662,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB)
-    public void browserApp_webUriUsedForBrowserApp() {
+    public void browserApp_transferSessionUriUsedForBrowserAppWhenAvailable() {
         // Make {@link AppToWebUtils#isBrowserApp} return true
         ResolveInfo resolveInfo = new ResolveInfo();
         resolveInfo.handleAllWebDataURI = true;
@@ -1648,7 +1673,7 @@
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
         final DesktopModeWindowDecoration decor = createWindowDecoration(
                 taskInfo, TEST_URI1 /* captured link */, TEST_URI2 /* web uri */,
-                TEST_URI3 /* generic link */);
+                null /* transfer session uri */, TEST_URI4 /* generic link */);
 
         // Verify web uri used for browser applications
         createHandleMenu(decor);
@@ -1656,8 +1681,29 @@
     }
 
 
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB)
+    public void browserApp_webUriUsedForBrowserAppWhenTransferSessionUriUnavailable() {
+        // Make {@link AppToWebUtils#isBrowserApp} return true
+        ResolveInfo resolveInfo = new ResolveInfo();
+        resolveInfo.handleAllWebDataURI = true;
+        resolveInfo.activityInfo = createActivityInfo();
+        when(mMockPackageManager.queryIntentActivitiesAsUser(any(), anyInt(), anyInt()))
+                .thenReturn(List.of(resolveInfo));
+
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+        final DesktopModeWindowDecoration decor = createWindowDecoration(
+                taskInfo, TEST_URI1 /* captured link */, TEST_URI2 /* web uri */,
+                TEST_URI3 /* transfer session uri */, TEST_URI4 /* generic link */);
+
+        // Verify web uri used for browser applications
+        createHandleMenu(decor);
+        verifyHandleMenuCreated(TEST_URI3);
+    }
+
+
     private void verifyHandleMenuCreated(@Nullable Uri uri) {
-        verify(mMockHandleMenuFactory).create(any(), any(), anyInt(), any(), any(),
+        verify(mMockHandleMenuFactory).create(any(), any(), any(), any(), any(), anyInt(),
                 any(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(),
                 anyBoolean(), argThat(intent ->
                         (uri == null && intent == null) || intent.getData().equals(uri)),
@@ -1692,10 +1738,11 @@
 
     private DesktopModeWindowDecoration createWindowDecoration(
             ActivityManager.RunningTaskInfo taskInfo, @Nullable Uri capturedLink,
-            @Nullable Uri webUri, @Nullable Uri genericLink) {
+            @Nullable Uri webUri, @Nullable Uri sessionTransferUri, @Nullable Uri genericLink) {
         taskInfo.capturedLink = capturedLink;
         taskInfo.capturedLinkTimestamp = System.currentTimeMillis();
         mAssistContent.setWebUri(webUri);
+        mAssistContent.getExtras().putObject(EXTRA_SESSION_TRANSFER_WEB_URI, sessionTransferUri);
         final String genericLinkString = genericLink == null ? null : genericLink.toString();
         doReturn(genericLinkString).when(mMockGenericLinksParser).getGenericLink(any());
         // Relayout to set captured link
@@ -1724,12 +1771,14 @@
             MaximizeMenuFactory maximizeMenuFactory,
             boolean relayout) {
         final DesktopModeWindowDecoration windowDecor = new DesktopModeWindowDecoration(mContext,
-                mContext, mMockDisplayController, mMockSplitScreenController,
-                mMockDesktopUserRepositories, mMockShellTaskOrganizer, taskInfo,
-                mMockSurfaceControl, mMockHandler, mBgExecutor, mMockChoreographer, mMockSyncQueue,
-                mMockAppHeaderViewHolderFactory, mMockRootTaskDisplayAreaOrganizer,
-                mMockGenericLinksParser, mMockAssistContentRequester, SurfaceControl.Builder::new,
-                mMockTransactionSupplier, WindowContainerTransaction::new, SurfaceControl::new,
+                mContext, mMockDisplayController, mMockTaskResourceLoader,
+                mMockSplitScreenController, mMockDesktopUserRepositories, mMockShellTaskOrganizer,
+                taskInfo, mMockSurfaceControl, mMockHandler, mMainExecutor,
+                mMockMainCoroutineDispatcher, mMockBgCoroutineScope, mBgExecutor,
+                mMockChoreographer, mMockSyncQueue, mMockAppHeaderViewHolderFactory,
+                mMockRootTaskDisplayAreaOrganizer, mMockGenericLinksParser,
+                mMockAssistContentRequester, SurfaceControl.Builder::new, mMockTransactionSupplier,
+                WindowContainerTransaction::new, SurfaceControl::new,
                 new WindowManagerWrapper(mMockWindowManager), mMockSurfaceControlViewHostFactory,
                 mMockWindowDecorViewHostSupplier, maximizeMenuFactory, mMockHandleMenuFactory,
                 mMockMultiInstanceHelper, mMockCaptionHandleRepository, mDesktopModeEventLogger);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
index 6babf81..cbfb57e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
@@ -24,6 +24,7 @@
 import android.graphics.Color
 import android.graphics.Point
 import android.graphics.Rect
+import android.graphics.drawable.BitmapDrawable
 import android.platform.test.annotations.EnableFlags
 import android.platform.test.flag.junit.SetFlagsRule
 import android.testing.AndroidTestingRunner
@@ -49,6 +50,13 @@
 import com.android.wm.shell.splitscreen.SplitScreenController
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewHostViewContainer
+import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader
+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.advanceUntilIdle
+import kotlinx.coroutines.test.runTest
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertTrue
 import org.junit.Before
@@ -68,6 +76,7 @@
  * Build/Install/Run:
  * atest WMShellUnitTests:HandleMenuTest
  */
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @TestableLooper.RunWithLooper
 @RunWith(AndroidTestingRunner::class)
@@ -81,14 +90,6 @@
     @Mock
     private lateinit var mockWindowManager: WindowManager
     @Mock
-    private lateinit var onClickListener: View.OnClickListener
-    @Mock
-    private lateinit var onTouchListener: View.OnTouchListener
-    @Mock
-    private lateinit var appIcon: Bitmap
-    @Mock
-    private lateinit var appName: CharSequence
-    @Mock
     private lateinit var displayController: DisplayController
     @Mock
     private lateinit var splitScreenController: SplitScreenController
@@ -96,6 +97,10 @@
     private lateinit var displayLayout: DisplayLayout
     @Mock
     private lateinit var mockSurfaceControlViewHost: SurfaceControlViewHost
+    @Mock
+    private lateinit var mockTaskResourceLoader: WindowDecorTaskResourceLoader
+    @Mock
+    private lateinit var mockAppIcon: Bitmap
 
     private lateinit var handleMenu: HandleMenu
 
@@ -136,7 +141,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_HANDLE_INPUT_FIX)
-    fun testFullscreenMenuUsesSystemViewContainer() {
+    fun testFullscreenMenuUsesSystemViewContainer() = runTest {
         createTaskInfo(WINDOWING_MODE_FULLSCREEN, SPLIT_POSITION_UNDEFINED)
         val handleMenu = createAndShowHandleMenu(SPLIT_POSITION_UNDEFINED)
         assertTrue(handleMenu.handleMenuViewContainer is AdditionalSystemViewContainer)
@@ -148,7 +153,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_HANDLE_INPUT_FIX)
-    fun testFreeformMenu_usesViewHostViewContainer() {
+    fun testFreeformMenu_usesViewHostViewContainer() = runTest {
         createTaskInfo(WINDOWING_MODE_FREEFORM, SPLIT_POSITION_UNDEFINED)
         handleMenu = createAndShowHandleMenu(SPLIT_POSITION_UNDEFINED)
         assertTrue(handleMenu.handleMenuViewContainer is AdditionalViewHostViewContainer)
@@ -159,7 +164,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_HANDLE_INPUT_FIX)
-    fun testSplitLeftMenu_usesSystemViewContainer() {
+    fun testSplitLeftMenu_usesSystemViewContainer() = runTest {
         createTaskInfo(WINDOWING_MODE_MULTI_WINDOW, SPLIT_POSITION_TOP_OR_LEFT)
         handleMenu = createAndShowHandleMenu(SPLIT_POSITION_TOP_OR_LEFT)
         assertTrue(handleMenu.handleMenuViewContainer is AdditionalSystemViewContainer)
@@ -174,7 +179,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_HANDLE_INPUT_FIX)
-    fun testSplitRightMenu_usesSystemViewContainer() {
+    fun testSplitRightMenu_usesSystemViewContainer() = runTest {
         createTaskInfo(WINDOWING_MODE_MULTI_WINDOW, SPLIT_POSITION_BOTTOM_OR_RIGHT)
         handleMenu = createAndShowHandleMenu(SPLIT_POSITION_BOTTOM_OR_RIGHT)
         assertTrue(handleMenu.handleMenuViewContainer is AdditionalSystemViewContainer)
@@ -188,7 +193,7 @@
     }
 
     @Test
-    fun testCreate_forceShowSystemBars_usesSystemViewContainer() {
+    fun testCreate_forceShowSystemBars_usesSystemViewContainer() = runTest {
         createTaskInfo(WINDOWING_MODE_FREEFORM)
 
         handleMenu = createAndShowHandleMenu(forceShowSystemBars = true)
@@ -198,7 +203,7 @@
     }
 
     @Test
-    fun testCreate_forceShowSystemBars() {
+    fun testCreate_forceShowSystemBars() = runTest {
         createTaskInfo(WINDOWING_MODE_FREEFORM)
 
         handleMenu = createAndShowHandleMenu(forceShowSystemBars = true)
@@ -208,6 +213,18 @@
         assertTrue((types and systemBars()) != 0)
     }
 
+    @Test
+    fun testCreate_loadsAppInfoInBackground() = runTest {
+        createTaskInfo(WINDOWING_MODE_FREEFORM)
+
+        handleMenu = createAndShowHandleMenu()
+        advanceUntilIdle()
+
+        assertThat(handleMenu.handleMenuView!!.appNameView.text).isEqualTo(APP_NAME)
+        val drawable = handleMenu.handleMenuView!!.appIconView.drawable as BitmapDrawable
+        assertThat(drawable.bitmap).isEqualTo(mockAppIcon)
+    }
+
     private fun createTaskInfo(windowingMode: Int, splitPosition: Int? = null) {
         val taskDescriptionBuilder = ActivityManager.TaskDescription.Builder()
             .setBackgroundColor(Color.YELLOW)
@@ -238,9 +255,13 @@
                 (it.arguments[1] as Rect).set(SPLIT_RIGHT_BOUNDS)
             }
         }
+        whenever(mockTaskResourceLoader.getName(mockDesktopWindowDecoration.mTaskInfo))
+            .thenReturn(APP_NAME)
+        whenever(mockTaskResourceLoader.getHeaderIcon(mockDesktopWindowDecoration.mTaskInfo))
+            .thenReturn(mockAppIcon)
     }
 
-    private fun createAndShowHandleMenu(
+    private fun TestScope.createAndShowHandleMenu(
         splitPosition: Int? = null,
         forceShowSystemBars: Boolean = false
     ): HandleMenu {
@@ -257,17 +278,27 @@
                 if (splitPosition == SPLIT_POSITION_TOP_OR_LEFT) {
                     (SPLIT_LEFT_BOUNDS.width() / 2) - (HANDLE_WIDTH / 2)
                 } else {
-                    (SPLIT_RIGHT_BOUNDS.width() / 2) - (HANDLE_WIDTH / 2)
+                    SPLIT_LEFT_BOUNDS.width() + (SPLIT_RIGHT_BOUNDS.width() / 2) - (HANDLE_WIDTH / 2)
                 }
             }
             else -> error("Invalid windowing mode")
         }
-        val handleMenu = HandleMenu(mockDesktopWindowDecoration,
+        val handleMenu = HandleMenu(
+            StandardTestDispatcher(testScheduler),
+            this,
+            mockDesktopWindowDecoration,
             WindowManagerWrapper(mockWindowManager),
-            layoutId, appIcon, appName, splitScreenController, shouldShowWindowingPill = true,
-            shouldShowNewWindowButton = true, shouldShowManageWindowsButton = false,
-            shouldShowChangeAspectRatioButton = false, shouldShowDesktopModeButton = true,
-            isBrowserApp = false, null /* openInAppOrBrowserIntent */, captionWidth = HANDLE_WIDTH,
+            mockTaskResourceLoader,
+            layoutId,
+            splitScreenController,
+            shouldShowWindowingPill = true,
+            shouldShowNewWindowButton = true,
+            shouldShowManageWindowsButton = false,
+            shouldShowChangeAspectRatioButton = false,
+            shouldShowDesktopModeButton = true,
+            isBrowserApp = false,
+            null /* openInAppOrBrowserIntent */,
+            captionWidth = HANDLE_WIDTH,
             captionHeight = 50,
             captionX = captionX,
             captionY = 0,
@@ -300,5 +331,6 @@
         private const val MENU_PILL_ELEVATION = 2
         private const val MENU_PILL_SPACING_MARGIN = 4
         private const val HANDLE_WIDTH = 80
+        private const val APP_NAME = "Test App"
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeVeilTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeVeilTest.kt
index e0d16aa..fa3d3e4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeVeilTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeVeilTest.kt
@@ -17,6 +17,7 @@
 
 import android.graphics.Bitmap
 import android.graphics.Rect
+import android.graphics.drawable.BitmapDrawable
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.Display
@@ -29,6 +30,13 @@
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.DisplayController.OnDisplaysChangedListener
 import com.android.wm.shell.windowdecor.WindowDecoration.SurfaceControlViewHostFactory
+import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader
+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.advanceUntilIdle
+import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -54,6 +62,7 @@
  * Build/Install/Run:
  * atest WMShellUnitTests:ResizeVeilTest
  */
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 @TestableLooper.RunWithLooper
@@ -85,6 +94,8 @@
     private lateinit var mockIconSurface: SurfaceControl
     @Mock
     private lateinit var mockTransaction: SurfaceControl.Transaction
+    @Mock
+    private lateinit var mockTaskResourceLoader: WindowDecorTaskResourceLoader
 
     private val taskInfo = TestRunningTaskInfoBuilder().build()
 
@@ -115,7 +126,7 @@
     }
 
     @Test
-    fun init_displayAvailable_viewHostCreated() {
+    fun init_displayAvailable_viewHostCreated() = runTest {
         createResizeVeil(withDisplayAvailable = true)
 
         verify(mockSurfaceControlViewHostFactory)
@@ -123,7 +134,7 @@
     }
 
     @Test
-    fun init_displayUnavailable_viewHostNotCreatedUntilDisplayAppears() {
+    fun init_displayUnavailable_viewHostNotCreatedUntilDisplayAppears() = runTest {
         createResizeVeil(withDisplayAvailable = false)
 
         verify(mockSurfaceControlViewHostFactory, never())
@@ -140,14 +151,14 @@
     }
 
     @Test
-    fun dispose_removesDisplayWindowListener() {
+    fun dispose_removesDisplayWindowListener() = runTest {
         createResizeVeil().dispose()
 
         verify(mockDisplayController).removeDisplayWindowListener(any())
     }
 
     @Test
-    fun showVeil() {
+    fun showVeil() = runTest {
         val veil = createResizeVeil()
 
         veil.showVeil(mockTransaction, mock(), Rect(0, 0, 100, 100), taskInfo, false /* fadeIn */)
@@ -159,7 +170,7 @@
     }
 
     @Test
-    fun showVeil_displayUnavailable_doesNotShow() {
+    fun showVeil_displayUnavailable_doesNotShow() = runTest {
         val veil = createResizeVeil(withDisplayAvailable = false)
 
         veil.showVeil(mockTransaction, mock(), Rect(0, 0, 100, 100), taskInfo, false /* fadeIn */)
@@ -171,7 +182,7 @@
     }
 
     @Test
-    fun showVeil_alreadyVisible_doesNotShowAgain() {
+    fun showVeil_alreadyVisible_doesNotShowAgain() = runTest {
         val veil = createResizeVeil()
 
         veil.showVeil(mockTransaction, mock(), Rect(0, 0, 100, 100), taskInfo, false /* fadeIn */)
@@ -184,7 +195,7 @@
     }
 
     @Test
-    fun showVeil_reparentsVeilToNewParent() {
+    fun showVeil_reparentsVeilToNewParent() = runTest {
         val veil = createResizeVeil(parent = mock())
 
         val newParent = mock<SurfaceControl>()
@@ -200,7 +211,7 @@
     }
 
     @Test
-    fun hideVeil_alreadyHidden_doesNothing() {
+    fun hideVeil_alreadyHidden_doesNothing() = runTest {
         val veil = createResizeVeil()
 
         veil.hideVeil()
@@ -208,16 +219,41 @@
         verifyZeroInteractions(mockTransaction)
     }
 
-    private fun createResizeVeil(
+    @Test
+    fun showVeil_loadsIconInBackground() = runTest {
+        val veil = createResizeVeil()
+        veil.showVeil(mockTransaction, mock(), Rect(0, 0, 100, 100), taskInfo, false /* fadeIn */)
+
+        advanceUntilIdle()
+
+        verify(mockTaskResourceLoader).getVeilIcon(taskInfo)
+        assertThat((veil.iconView.drawable as BitmapDrawable).bitmap).isEqualTo(mockAppIcon)
+    }
+
+    @Test
+    fun dispose_iconLoading_cancelsJob() = runTest {
+        val veil = createResizeVeil()
+        veil.showVeil(mockTransaction, mock(), Rect(0, 0, 100, 100), taskInfo, false /* fadeIn */)
+
+        veil.dispose()
+        advanceUntilIdle()
+
+        assertThat(veil.iconView.drawable).isNull()
+    }
+
+    private fun TestScope.createResizeVeil(
         withDisplayAvailable: Boolean = true,
         parent: SurfaceControl = mock()
     ): ResizeVeil {
         whenever(mockDisplayController.getDisplay(taskInfo.displayId))
             .thenReturn(if (withDisplayAvailable) mockDisplay else null)
+        whenever(mockTaskResourceLoader.getVeilIcon(taskInfo)).thenReturn(mockAppIcon)
         return ResizeVeil(
             context,
             mockDisplayController,
-            mockAppIcon,
+            mockTaskResourceLoader,
+            StandardTestDispatcher(testScheduler),
+            this,
             parent,
             { mockTransaction },
             mockSurfaceControlBuilderFactory,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/DesktopMenuPositionUtilityTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/DesktopMenuPositionUtilityTest.kt
new file mode 100644
index 0000000..7b42ff4
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/DesktopMenuPositionUtilityTest.kt
@@ -0,0 +1,201 @@
+/*
+ * 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.common
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestRunningTaskInfoBuilder
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
+import com.android.wm.shell.splitscreen.SplitScreenController
+import org.junit.runner.RunWith
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
+
+/**
+ * Tests for [DesktopMenuPositionUtility].
+ *
+ * Build/Install/Run: atest WMShellUnitTests:DesktopMenuPositionUtilityTest
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class DesktopMenuPositionUtilityTest : ShellTestCase() {
+
+    @Mock private val mockSplitScreenController = mock<SplitScreenController>()
+
+    @Test
+    fun testFullscreenPositionCalculation() {
+        val task = setupTaskInfo(WINDOWING_MODE_FULLSCREEN)
+        val result =
+            calculateMenuPosition(
+                splitScreenController = mockSplitScreenController,
+                taskInfo = task,
+                MARGIN_START,
+                MARGIN_TOP,
+                CAPTION_X,
+                CAPTION_Y,
+                CAPTION_WIDTH,
+                MENU_WIDTH,
+                isRtl = false,
+            )
+        assertEquals(CAPTION_X + (CAPTION_WIDTH / 2) - (MENU_WIDTH / 2), result.x)
+        assertEquals(CAPTION_Y + MARGIN_TOP, result.y)
+    }
+
+    @Test
+    fun testSplitLeftPositionCalculation() {
+        val task = setupTaskInfo(WINDOWING_MODE_MULTI_WINDOW)
+        setupMockSplitScreenController(
+            splitPosition = SPLIT_POSITION_TOP_OR_LEFT,
+            isLeftRightSplit = true,
+        )
+        val result =
+            calculateMenuPosition(
+                splitScreenController = mockSplitScreenController,
+                taskInfo = task,
+                MARGIN_START,
+                MARGIN_TOP,
+                CAPTION_X,
+                CAPTION_Y,
+                CAPTION_WIDTH,
+                MENU_WIDTH,
+                isRtl = false,
+            )
+        assertEquals(CAPTION_X + (CAPTION_WIDTH / 2) - (MENU_WIDTH / 2), result.x)
+        assertEquals(CAPTION_Y + MARGIN_TOP, result.y)
+    }
+
+    @Test
+    fun testSplitRightPositionCalculation() {
+        val task = setupTaskInfo(WINDOWING_MODE_MULTI_WINDOW)
+        setupMockSplitScreenController(
+            splitPosition = SPLIT_POSITION_BOTTOM_OR_RIGHT,
+            isLeftRightSplit = true,
+        )
+        val result =
+            calculateMenuPosition(
+                splitScreenController = mockSplitScreenController,
+                taskInfo = task,
+                MARGIN_START,
+                MARGIN_TOP,
+                CAPTION_X,
+                CAPTION_Y,
+                CAPTION_WIDTH,
+                MENU_WIDTH,
+                isRtl = false,
+            )
+        assertEquals(
+            CAPTION_X + (CAPTION_WIDTH / 2) - (MENU_WIDTH / 2) + SPLIT_LEFT_BOUNDS.width(),
+            result.x,
+        )
+        assertEquals(CAPTION_Y + MARGIN_TOP, result.y)
+    }
+
+    @Test
+    fun testSplitTopPositionCalculation() {
+        val task = setupTaskInfo(WINDOWING_MODE_MULTI_WINDOW)
+        setupMockSplitScreenController(
+            splitPosition = SPLIT_POSITION_TOP_OR_LEFT,
+            isLeftRightSplit = false,
+        )
+        val result =
+            calculateMenuPosition(
+                splitScreenController = mockSplitScreenController,
+                taskInfo = task,
+                MARGIN_START,
+                MARGIN_TOP,
+                CAPTION_X,
+                CAPTION_Y,
+                CAPTION_WIDTH,
+                MENU_WIDTH,
+                isRtl = false,
+            )
+        assertEquals(CAPTION_X + (CAPTION_WIDTH / 2) - (MENU_WIDTH / 2), result.x)
+        assertEquals(CAPTION_Y + MARGIN_TOP, result.y)
+    }
+
+    @Test
+    fun testSplitBottomPositionCalculation() {
+        val task = setupTaskInfo(WINDOWING_MODE_MULTI_WINDOW)
+        setupMockSplitScreenController(
+            splitPosition = SPLIT_POSITION_BOTTOM_OR_RIGHT,
+            isLeftRightSplit = false,
+        )
+        val result =
+            calculateMenuPosition(
+                splitScreenController = mockSplitScreenController,
+                taskInfo = task,
+                MARGIN_START,
+                MARGIN_TOP,
+                CAPTION_X,
+                CAPTION_Y,
+                CAPTION_WIDTH,
+                MENU_WIDTH,
+                isRtl = false,
+            )
+        assertEquals(CAPTION_X + (CAPTION_WIDTH / 2) - (MENU_WIDTH / 2), result.x)
+        assertEquals(CAPTION_Y + MARGIN_TOP + SPLIT_TOP_BOUNDS.height(), result.y)
+    }
+
+    private fun setupTaskInfo(windowingMode: Int): RunningTaskInfo {
+        return TestRunningTaskInfoBuilder().setWindowingMode(windowingMode).build()
+    }
+
+    private fun setupMockSplitScreenController(isLeftRightSplit: Boolean, splitPosition: Int) {
+        whenever(mockSplitScreenController.getSplitPosition(anyInt())).thenReturn(splitPosition)
+        whenever(mockSplitScreenController.getRefStageBounds(any(), any())).thenAnswer {
+            (it.arguments.first() as Rect).set(
+                if (isLeftRightSplit) {
+                    SPLIT_LEFT_BOUNDS
+                } else {
+                    SPLIT_TOP_BOUNDS
+                }
+            )
+            (it.arguments[1] as Rect).set(
+                if (isLeftRightSplit) {
+                    SPLIT_RIGHT_BOUNDS
+                } else {
+                    SPLIT_BOTTOM_BOUNDS
+                }
+            )
+        }
+        whenever(mockSplitScreenController.isLeftRightSplit).thenReturn(isLeftRightSplit)
+    }
+
+    companion object {
+        private val SPLIT_LEFT_BOUNDS = Rect(0, 0, 1280, 1600)
+        private val SPLIT_RIGHT_BOUNDS = Rect(1280, 0, 2560, 1600)
+        private val SPLIT_TOP_BOUNDS = Rect(0, 0, 2560, 800)
+        private val SPLIT_BOTTOM_BOUNDS = Rect(0, 800, 2560, 1600)
+        private const val CAPTION_X = 800
+        private const val CAPTION_Y = 50
+        private const val MARGIN_START = 30
+        private const val MARGIN_TOP = 50
+        private const val MENU_WIDTH = 500
+        private const val CAPTION_WIDTH = 200
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/WindowDecorTaskResourceLoaderTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/WindowDecorTaskResourceLoaderTest.kt
new file mode 100644
index 0000000..1ec0fe7
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/WindowDecorTaskResourceLoaderTest.kt
@@ -0,0 +1,224 @@
+/*
+ * 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.common
+
+import android.app.ActivityManager
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.content.pm.ActivityInfo
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
+import android.graphics.drawable.Drawable
+import android.os.UserHandle
+import android.testing.AndroidTestingRunner
+import android.testing.TestableContext
+import androidx.test.filters.SmallTest
+import com.android.launcher3.icons.BaseIconFactory
+import com.android.launcher3.icons.BaseIconFactory.MODE_DEFAULT
+import com.android.launcher3.icons.IconProvider
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestRunningTaskInfoBuilder
+import com.android.wm.shell.TestShellExecutor
+import com.android.wm.shell.sysui.ShellController
+import com.android.wm.shell.sysui.ShellInit
+import com.android.wm.shell.sysui.UserChangeListener
+import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader.AppResources
+import com.google.common.truth.Truth.assertThat
+import org.junit.Assert.assertThrows
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyFloat
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.verifyZeroInteractions
+import org.mockito.kotlin.whenever
+
+/**
+ * Tests for [WindowDecorTaskResourceLoader].
+ *
+ * Build/Install/Run: atest WindowDecorTaskResourceLoaderTest
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class WindowDecorTaskResourceLoaderTest : ShellTestCase() {
+    private val testExecutor = TestShellExecutor()
+    private val shellInit = ShellInit(testExecutor)
+    private val mockShellController = mock<ShellController>()
+    private val mockPackageManager = mock<PackageManager>()
+    private val mockIconProvider = mock<IconProvider>()
+    private val mockHeaderIconFactory = mock<BaseIconFactory>()
+    private val mockVeilIconFactory = mock<BaseIconFactory>()
+
+    private lateinit var spyContext: TestableContext
+    private lateinit var loader: WindowDecorTaskResourceLoader
+
+    private val userChangeListenerCaptor = argumentCaptor<UserChangeListener>()
+    private val userChangeListener: UserChangeListener by lazy {
+        userChangeListenerCaptor.firstValue
+    }
+
+    @Before
+    fun setUp() {
+        spyContext = spy(mContext)
+        spyContext.setMockPackageManager(mockPackageManager)
+        doReturn(spyContext).whenever(spyContext).createContextAsUser(any(), anyInt())
+        loader =
+            WindowDecorTaskResourceLoader(
+                context = spyContext,
+                shellInit = shellInit,
+                shellController = mockShellController,
+                shellCommandHandler = mock(),
+                iconProvider = mockIconProvider,
+                headerIconFactory = mockHeaderIconFactory,
+                veilIconFactory = mockVeilIconFactory,
+            )
+        shellInit.init()
+        testExecutor.flushAll()
+        verify(mockShellController).addUserChangeListener(userChangeListenerCaptor.capture())
+    }
+
+    @Test
+    fun testGetName_notCached_loadsResourceAndCaches() {
+        val task = createTaskInfo(context.userId)
+        loader.onWindowDecorCreated(task)
+
+        loader.getName(task)
+
+        verify(mockPackageManager).getApplicationLabel(task.topActivityInfo!!.applicationInfo)
+        assertThat(loader.taskToResourceCache[task.taskId]?.appName).isNotNull()
+    }
+
+    @Test
+    fun testGetName_cached_returnsFromCache() {
+        val task = createTaskInfo(context.userId)
+        loader.onWindowDecorCreated(task)
+        loader.taskToResourceCache[task.taskId] = AppResources("App Name", mock(), mock())
+
+        loader.getName(task)
+
+        verifyZeroInteractions(
+            mockPackageManager,
+            mockIconProvider,
+            mockHeaderIconFactory,
+            mockVeilIconFactory,
+        )
+    }
+
+    @Test
+    fun testGetHeaderIcon_notCached_loadsResourceAndCaches() {
+        val task = createTaskInfo(context.userId)
+        loader.onWindowDecorCreated(task)
+
+        loader.getHeaderIcon(task)
+
+        verify(mockHeaderIconFactory).createIconBitmap(any(), anyFloat())
+        assertThat(loader.taskToResourceCache[task.taskId]?.appIcon).isNotNull()
+    }
+
+    @Test
+    fun testGetHeaderIcon_cached_returnsFromCache() {
+        val task = createTaskInfo(context.userId)
+        loader.onWindowDecorCreated(task)
+        loader.taskToResourceCache[task.taskId] = AppResources("App Name", mock(), mock())
+
+        loader.getHeaderIcon(task)
+
+        verifyZeroInteractions(mockPackageManager, mockIconProvider, mockHeaderIconFactory)
+    }
+
+    @Test
+    fun testGetVeilIcon_notCached_loadsResourceAndCaches() {
+        val task = createTaskInfo(context.userId)
+        loader.onWindowDecorCreated(task)
+
+        loader.getVeilIcon(task)
+
+        verify(mockVeilIconFactory).createScaledBitmap(any(), anyInt())
+        assertThat(loader.taskToResourceCache[task.taskId]?.veilIcon).isNotNull()
+    }
+
+    @Test
+    fun testGetVeilIcon_cached_returnsFromCache() {
+        val task = createTaskInfo(context.userId)
+        loader.onWindowDecorCreated(task)
+        loader.taskToResourceCache[task.taskId] = AppResources("App Name", mock(), mock())
+
+        loader.getVeilIcon(task)
+
+        verifyZeroInteractions(mockPackageManager, mockIconProvider, mockVeilIconFactory)
+    }
+
+    @Test
+    fun testUserChange_updatesContext() {
+        val newUser = 5000
+        val newContext = mock<Context>()
+
+        userChangeListener.onUserChanged(newUser, newContext)
+
+        assertThat(loader.currentUserContext).isEqualTo(newContext)
+    }
+
+    @Test
+    fun testUserChange_clearsCache() {
+        val newUser = 5000
+        val newContext = mock<Context>()
+        val task = createTaskInfo(context.userId)
+        loader.onWindowDecorCreated(task)
+        loader.getName(task)
+
+        userChangeListener.onUserChanged(newUser, newContext)
+
+        assertThat(loader.taskToResourceCache[task.taskId]?.appName).isNull()
+    }
+
+    @Test
+    fun testGet_nonexistentDecor_throws() {
+        val task = createTaskInfo(context.userId)
+
+        assertThrows(Exception::class.java) { loader.getName(task) }
+    }
+
+    private fun createTaskInfo(userId: Int): ActivityManager.RunningTaskInfo {
+        val appIconDrawable = mock<Drawable>()
+        val badgedAppIconDrawable = mock<Drawable>()
+        val activityInfo = ActivityInfo().apply { applicationInfo = ApplicationInfo() }
+        val componentName = ComponentName("com.foo", "BarActivity")
+        whenever(mockPackageManager.getActivityInfo(eq(componentName), anyInt()))
+            .thenReturn(activityInfo)
+        whenever(mockPackageManager.getApplicationLabel(activityInfo.applicationInfo))
+            .thenReturn("Test App")
+        whenever(mockPackageManager.getUserBadgedIcon(appIconDrawable, UserHandle.of(userId)))
+            .thenReturn(badgedAppIconDrawable)
+        whenever(mockIconProvider.getIcon(activityInfo)).thenReturn(appIconDrawable)
+        whenever(mockHeaderIconFactory.createIconBitmap(badgedAppIconDrawable, 1f))
+            .thenReturn(mock())
+        whenever(mockVeilIconFactory.createScaledBitmap(appIconDrawable, MODE_DEFAULT))
+            .thenReturn(mock())
+        return TestRunningTaskInfoBuilder()
+            .setUserId(userId)
+            .setBaseIntent(Intent().apply { component = componentName })
+            .build()
+            .apply { topActivityInfo = activityInfo }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/PooledWindowDecorViewHostSupplierTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/PooledWindowDecorViewHostSupplierTest.kt
index 40583f8..92f5def 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/PooledWindowDecorViewHostSupplierTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/PooledWindowDecorViewHostSupplierTest.kt
@@ -18,14 +18,19 @@
 import android.content.res.Configuration
 import android.graphics.Region
 import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
 import android.view.SurfaceControl
 import android.view.View
 import android.view.WindowManager
 import androidx.test.filters.SmallTest
 import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestShellExecutor
+import com.android.wm.shell.sysui.ShellInit
 import com.android.wm.shell.util.StubTransaction
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.advanceUntilIdle
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -38,9 +43,13 @@
  * Build/Install/Run: atest WMShellUnitTests:PooledWindowDecorViewHostSupplierTest
  */
 @SmallTest
+@RunWithLooper
 @RunWith(AndroidTestingRunner::class)
 class PooledWindowDecorViewHostSupplierTest : ShellTestCase() {
 
+    private val testExecutor = TestShellExecutor()
+    private val testShellInit = ShellInit(testExecutor)
+
     private lateinit var supplier: PooledWindowDecorViewHostSupplier
 
     @Test
@@ -48,6 +57,27 @@
         MockitoAnnotations.initMocks(this)
     }
 
+    @OptIn(ExperimentalCoroutinesApi::class)
+    @Test
+    fun onInit_warmsAndPoolsViewHosts() = runTest {
+        supplier = createSupplier(maxPoolSize = 5, preWarmSize = 2)
+
+        testExecutor.flushAll()
+        advanceUntilIdle()
+
+        val viewHost1 = supplier.acquire(context, context.display) as ReusableWindowDecorViewHost
+        val viewHost2 = supplier.acquire(context, context.display) as ReusableWindowDecorViewHost
+
+        // Acquired warmed up view hosts from the pool.
+        assertThat(viewHost1.viewHostAdapter.isInitialized()).isTrue()
+        assertThat(viewHost2.viewHostAdapter.isInitialized()).isTrue()
+    }
+
+    @Test(expected = Throwable::class)
+    fun onInit_warmUpSizeExceedsPoolSize_throws() = runTest {
+        createSupplier(maxPoolSize = 3, preWarmSize = 4)
+    }
+
     @Test
     fun acquire_poolBelowLimit_caches() = runTest {
         supplier = createSupplier(maxPoolSize = 5)
@@ -97,8 +127,9 @@
         assertThat(viewHost2.released).isTrue()
     }
 
-    private fun CoroutineScope.createSupplier(maxPoolSize: Int) =
-        PooledWindowDecorViewHostSupplier(this, maxPoolSize)
+    private fun CoroutineScope.createSupplier(maxPoolSize: Int, preWarmSize: Int = 0) =
+        PooledWindowDecorViewHostSupplier(context, this, testShellInit, maxPoolSize, preWarmSize)
+            .also { testShellInit.init() }
 
     private class FakeWindowDecorViewHost : WindowDecorViewHost {
         var released = false
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/ReusableWindowDecorViewHostTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/ReusableWindowDecorViewHostTest.kt
index 245393a..d99a482 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/ReusableWindowDecorViewHostTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/ReusableWindowDecorViewHostTest.kt
@@ -157,6 +157,14 @@
         verify(reusableVH.viewHostAdapter).release(t)
     }
 
+    @Test
+    fun warmUp_addsRootView() = runTest {
+        val reusableVH = createReusableViewHost().apply { warmUp() }
+
+        assertThat(reusableVH.viewHostAdapter.isInitialized()).isTrue()
+        assertThat(reusableVH.view()).isEqualTo(reusableVH.rootView)
+    }
+
     private fun CoroutineScope.createReusableViewHost() =
         ReusableWindowDecorViewHost(
             context = context,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
index 193c2c2..997ece6e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
@@ -32,7 +32,10 @@
 import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler
 import com.android.wm.shell.transition.Transitions
 import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration
+import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.MainCoroutineDispatcher
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -47,6 +50,8 @@
 @RunWith(AndroidTestingRunner::class)
 class DesktopTilingDecorViewModelTest : ShellTestCase() {
     private val contextMock: Context = mock()
+    private val mainDispatcher: MainCoroutineDispatcher = mock()
+    private val bgScope: CoroutineScope = mock()
     private val displayControllerMock: DisplayController = mock()
     private val rootTdaOrganizerMock: RootTaskDisplayAreaOrganizer = mock()
     private val syncQueueMock: SyncTransactionQueue = mock()
@@ -61,6 +66,7 @@
 
     private val desktopModeWindowDecorationMock: DesktopModeWindowDecoration = mock()
     private val desktopTilingDecoration: DesktopTilingWindowDecoration = mock()
+    private val taskResourceLoader: WindowDecorTaskResourceLoader = mock()
     private lateinit var desktopTilingDecorViewModel: DesktopTilingDecorViewModel
 
     @Before
@@ -68,6 +74,8 @@
         desktopTilingDecorViewModel =
             DesktopTilingDecorViewModel(
                 contextMock,
+                mainDispatcher,
+                bgScope,
                 displayControllerMock,
                 rootTdaOrganizerMock,
                 syncQueueMock,
@@ -77,6 +85,7 @@
                 returnToDragStartAnimatorMock,
                 userRepositories,
                 desktopModeEventLogger,
+                taskResourceLoader,
             )
         whenever(contextMock.createContextAsUser(any(), any())).thenReturn(contextMock)
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
index 95e2151..2f15c2e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
@@ -45,7 +45,10 @@
 import com.android.wm.shell.transition.Transitions
 import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration
 import com.android.wm.shell.windowdecor.DragResizeWindowGeometry
+import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.MainCoroutineDispatcher
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -99,6 +102,9 @@
     private val desktopTilingDividerWindowManager: DesktopTilingDividerWindowManager = mock()
     private val motionEvent: MotionEvent = mock()
     private val desktopRepository: DesktopRepository = mock()
+    private val mainDispatcher: MainCoroutineDispatcher = mock()
+    private val bgScope: CoroutineScope = mock()
+    private val taskResourceLoader: WindowDecorTaskResourceLoader = mock()
     private lateinit var tilingDecoration: DesktopTilingWindowDecoration
 
     private val split_divider_width = 10
@@ -110,8 +116,11 @@
         tilingDecoration =
             DesktopTilingWindowDecoration(
                 context,
+                mainDispatcher,
+                bgScope,
                 syncQueue,
                 displayController,
+                taskResourceLoader,
                 displayId,
                 rootTdaOrganizer,
                 transitions,
diff --git a/libs/hwui/jni/text/TextShaper.cpp b/libs/hwui/jni/text/TextShaper.cpp
index c735989..d1782b2 100644
--- a/libs/hwui/jni/text/TextShaper.cpp
+++ b/libs/hwui/jni/text/TextShaper.cpp
@@ -225,8 +225,8 @@
 
 constexpr float NO_OVERRIDE = -1;
 
-float findValueFromVariationSettings(const minikin::FontFakery& fakery, minikin::AxisTag tag) {
-    for (const minikin::FontVariation& fv : fakery.variationSettings()) {
+float findValueFromVariationSettings(const minikin::VariationSettings& axes, minikin::AxisTag tag) {
+    for (const minikin::FontVariation& fv : axes) {
         if (fv.axisTag == tag) {
             return fv.value;
         }
@@ -238,8 +238,8 @@
 static jfloat TextShaper_Result_getWeightOverride(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) {
     const LayoutWrapper* layout = reinterpret_cast<LayoutWrapper*>(ptr);
     if (text_feature::typeface_redesign_readonly()) {
-        float value =
-                findValueFromVariationSettings(layout->layout.getFakery(i), minikin::TAG_wght);
+        float value = findValueFromVariationSettings(layout->layout.typeface(i)->GetAxes(),
+                                                     minikin::TAG_wght);
         return std::isnan(value) ? NO_OVERRIDE : value;
     } else {
         return layout->layout.getFakery(i).wghtAdjustment();
@@ -250,8 +250,8 @@
 static jfloat TextShaper_Result_getItalicOverride(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) {
     const LayoutWrapper* layout = reinterpret_cast<LayoutWrapper*>(ptr);
     if (text_feature::typeface_redesign_readonly()) {
-        float value =
-                findValueFromVariationSettings(layout->layout.getFakery(i), minikin::TAG_ital);
+        float value = findValueFromVariationSettings(layout->layout.typeface(i)->GetAxes(),
+                                                     minikin::TAG_ital);
         return std::isnan(value) ? NO_OVERRIDE : value;
     } else {
         return layout->layout.getFakery(i).italAdjustment();
diff --git a/location/api/system-current.txt b/location/api/system-current.txt
index 9478e35..ba42241 100644
--- a/location/api/system-current.txt
+++ b/location/api/system-current.txt
@@ -6,6 +6,111 @@
     method public void onLocationBatch(java.util.List<android.location.Location>);
   }
 
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class BeidouAssistance implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public android.location.GnssAlmanac getAlmanac();
+    method @Nullable public android.location.KlobucharIonosphericModel getIonosphericModel();
+    method @Nullable public android.location.LeapSecondsModel getLeapSecondsModel();
+    method @NonNull public java.util.List<android.location.RealTimeIntegrityModel> getRealTimeIntegrityModels();
+    method @NonNull public java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections> getSatelliteCorrections();
+    method @NonNull public java.util.List<android.location.BeidouSatelliteEphemeris> getSatelliteEphemeris();
+    method @NonNull public java.util.List<android.location.TimeModel> getTimeModels();
+    method @Nullable public android.location.UtcModel getUtcModel();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.BeidouAssistance> CREATOR;
+  }
+
+  public static final class BeidouAssistance.Builder {
+    ctor public BeidouAssistance.Builder();
+    method @NonNull public android.location.BeidouAssistance build();
+    method @NonNull public android.location.BeidouAssistance.Builder setAlmanac(@Nullable android.location.GnssAlmanac);
+    method @NonNull public android.location.BeidouAssistance.Builder setIonosphericModel(@Nullable android.location.KlobucharIonosphericModel);
+    method @NonNull public android.location.BeidouAssistance.Builder setLeapSecondsModel(@Nullable android.location.LeapSecondsModel);
+    method @NonNull public android.location.BeidouAssistance.Builder setRealTimeIntegrityModels(@Nullable java.util.List<android.location.RealTimeIntegrityModel>);
+    method @NonNull public android.location.BeidouAssistance.Builder setSatelliteCorrections(@Nullable java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections>);
+    method @NonNull public android.location.BeidouAssistance.Builder setSatelliteEphemeris(@Nullable java.util.List<android.location.BeidouSatelliteEphemeris>);
+    method @NonNull public android.location.BeidouAssistance.Builder setTimeModels(@Nullable java.util.List<android.location.TimeModel>);
+    method @NonNull public android.location.BeidouAssistance.Builder setUtcModel(@Nullable android.location.UtcModel);
+  }
+
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class BeidouSatelliteEphemeris implements android.os.Parcelable {
+    method public int describeContents();
+    method @IntRange(from=1, to=63) public int getPrn();
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel getSatelliteClockModel();
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime getSatelliteEphemerisTime();
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteHealth getSatelliteHealth();
+    method @NonNull public android.location.KeplerianOrbitModel getSatelliteOrbitModel();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.BeidouSatelliteEphemeris> CREATOR;
+  }
+
+  public static final class BeidouSatelliteEphemeris.BeidouSatelliteClockModel implements android.os.Parcelable {
+    method public int describeContents();
+    method @FloatRange(from=-0.00977F, to=0.00977f) public double getAf0();
+    method @FloatRange(from=-1.87E-9F, to=1.87E-9f) public double getAf1();
+    method @FloatRange(from=-1.39E-17F, to=1.39E-17f) public double getAf2();
+    method @IntRange(from=0, to=31) public int getAodc();
+    method @FloatRange(from=-5.12E-8F, to=5.12E-8f) public double getTgd1();
+    method @FloatRange(from=-5.12E-8F, to=5.12E-8f) public double getTgd2();
+    method @IntRange(from=0) public long getTimeOfClockSeconds();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel> CREATOR;
+  }
+
+  public static final class BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder {
+    ctor public BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder();
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel build();
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder setAf0(@FloatRange(from=-0.00977F, to=0.00977f) double);
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder setAf1(@FloatRange(from=-1.87E-9F, to=1.87E-9f) double);
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder setAf2(@FloatRange(from=-1.39E-17F, to=1.39E-17f) double);
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder setAodc(@IntRange(from=0, to=31) int);
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder setTgd1(@FloatRange(from=-5.12E-8F, to=5.12E-8f) double);
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder setTgd2(@FloatRange(from=-5.12E-8F, to=5.12E-8f) double);
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder setTimeOfClockSeconds(@IntRange(from=0) long);
+  }
+
+  public static final class BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime implements android.os.Parcelable {
+    method public int describeContents();
+    method @IntRange(from=0) public int getBeidouWeekNumber();
+    method @IntRange(from=0, to=31) public int getIode();
+    method @IntRange(from=0, to=604792) public int getToeSeconds();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime> CREATOR;
+  }
+
+  public static final class BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime.Builder {
+    ctor public BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime.Builder();
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime build();
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime.Builder setBeidouWeekNumber(@IntRange(from=0) int);
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime.Builder setIode(int);
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime.Builder setToeSeconds(@IntRange(from=0, to=604792) int);
+  }
+
+  public static final class BeidouSatelliteEphemeris.BeidouSatelliteHealth implements android.os.Parcelable {
+    method public int describeContents();
+    method @IntRange(from=0, to=1) public int getSatH1();
+    method @FloatRange(from=0.0f, to=8192.0f) public double getSvAccur();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.BeidouSatelliteEphemeris.BeidouSatelliteHealth> CREATOR;
+  }
+
+  public static final class BeidouSatelliteEphemeris.BeidouSatelliteHealth.Builder {
+    ctor public BeidouSatelliteEphemeris.BeidouSatelliteHealth.Builder();
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteHealth build();
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteHealth.Builder setSatH1(int);
+    method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteHealth.Builder setSvAccur(double);
+  }
+
+  public static final class BeidouSatelliteEphemeris.Builder {
+    ctor public BeidouSatelliteEphemeris.Builder();
+    method @NonNull public android.location.BeidouSatelliteEphemeris build();
+    method @NonNull public android.location.BeidouSatelliteEphemeris.Builder setPrn(int);
+    method @NonNull public android.location.BeidouSatelliteEphemeris.Builder setSatelliteClockModel(@NonNull android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel);
+    method @NonNull public android.location.BeidouSatelliteEphemeris.Builder setSatelliteEphemerisTime(@NonNull android.location.BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime);
+    method @NonNull public android.location.BeidouSatelliteEphemeris.Builder setSatelliteHealth(@NonNull android.location.BeidouSatelliteEphemeris.BeidouSatelliteHealth);
+    method @NonNull public android.location.BeidouSatelliteEphemeris.Builder setSatelliteOrbitModel(@NonNull android.location.KeplerianOrbitModel);
+  }
+
   public final class CorrelationVector implements android.os.Parcelable {
     method public int describeContents();
     method @FloatRange(from=0.0f) public double getFrequencyOffsetMetersPerSecond();
@@ -43,12 +148,375 @@
     method public void unregisterCountryDetectorCallback(@NonNull java.util.function.Consumer<android.location.Country>);
   }
 
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GalileoAssistance implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public android.location.GnssAlmanac getAlmanac();
+    method @Nullable public android.location.KlobucharIonosphericModel getIonosphericModel();
+    method @Nullable public android.location.LeapSecondsModel getLeapSecondsModel();
+    method @NonNull public java.util.List<android.location.RealTimeIntegrityModel> getRealTimeIntegrityModels();
+    method @NonNull public java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections> getSatelliteCorrections();
+    method @NonNull public java.util.List<android.location.GalileoSatelliteEphemeris> getSatelliteEphemeris();
+    method @NonNull public java.util.List<android.location.TimeModel> getTimeModels();
+    method @Nullable public android.location.UtcModel getUtcModel();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GalileoAssistance> CREATOR;
+  }
+
+  public static final class GalileoAssistance.Builder {
+    ctor public GalileoAssistance.Builder();
+    method @NonNull public android.location.GalileoAssistance build();
+    method @NonNull public android.location.GalileoAssistance.Builder setAlmanac(@Nullable android.location.GnssAlmanac);
+    method @NonNull public android.location.GalileoAssistance.Builder setIonosphericModel(@Nullable android.location.KlobucharIonosphericModel);
+    method @NonNull public android.location.GalileoAssistance.Builder setLeapSecondsModel(@Nullable android.location.LeapSecondsModel);
+    method @NonNull public android.location.GalileoAssistance.Builder setRealTimeIntegrityModels(@Nullable java.util.List<android.location.RealTimeIntegrityModel>);
+    method @NonNull public android.location.GalileoAssistance.Builder setSatelliteCorrections(@Nullable java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections>);
+    method @NonNull public android.location.GalileoAssistance.Builder setSatelliteEphemeris(@Nullable java.util.List<android.location.GalileoSatelliteEphemeris>);
+    method @NonNull public android.location.GalileoAssistance.Builder setTimeModels(@Nullable java.util.List<android.location.TimeModel>);
+    method @NonNull public android.location.GalileoAssistance.Builder setUtcModel(@Nullable android.location.UtcModel);
+  }
+
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GalileoIonosphericModel implements android.os.Parcelable {
+    method public int describeContents();
+    method @FloatRange(from=0.0f, to=512.0f) public double getAi0();
+    method @FloatRange(from=-4.0F, to=4.0f) public double getAi1();
+    method @FloatRange(from=-0.5F, to=0.5f) public double getAi2();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GalileoIonosphericModel> CREATOR;
+  }
+
+  public static final class GalileoIonosphericModel.Builder {
+    ctor public GalileoIonosphericModel.Builder();
+    method @NonNull public android.location.GalileoIonosphericModel build();
+    method @NonNull public android.location.GalileoIonosphericModel.Builder setAi0(@FloatRange(from=0.0f, to=512.0f) double);
+    method @NonNull public android.location.GalileoIonosphericModel.Builder setAi1(@FloatRange(from=-4.0F, to=4.0f) double);
+    method @NonNull public android.location.GalileoIonosphericModel.Builder setAi2(@FloatRange(from=-0.5F, to=0.5f) double);
+  }
+
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GalileoSatelliteEphemeris implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.List<android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel> getSatelliteClockModels();
+    method @IntRange(from=1, to=36) public int getSatelliteCodeNumber();
+    method @NonNull public android.location.SatelliteEphemerisTime getSatelliteEphemerisTime();
+    method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSvHealth getSatelliteHealth();
+    method @NonNull public android.location.KeplerianOrbitModel getSatelliteOrbitModel();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GalileoSatelliteEphemeris> CREATOR;
+  }
+
+  public static final class GalileoSatelliteEphemeris.Builder {
+    ctor public GalileoSatelliteEphemeris.Builder();
+    method @NonNull public android.location.GalileoSatelliteEphemeris build();
+    method @NonNull public android.location.GalileoSatelliteEphemeris.Builder setSatelliteClockModels(@NonNull java.util.List<android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel>);
+    method @NonNull public android.location.GalileoSatelliteEphemeris.Builder setSatelliteCodeNumber(@IntRange(from=1, to=36) int);
+    method @NonNull public android.location.GalileoSatelliteEphemeris.Builder setSatelliteEphemerisTime(@NonNull android.location.SatelliteEphemerisTime);
+    method @NonNull public android.location.GalileoSatelliteEphemeris.Builder setSatelliteHealth(@NonNull android.location.GalileoSatelliteEphemeris.GalileoSvHealth);
+    method @NonNull public android.location.GalileoSatelliteEphemeris.Builder setSatelliteOrbitModel(@NonNull android.location.KeplerianOrbitModel);
+  }
+
+  public static final class GalileoSatelliteEphemeris.GalileoSatelliteClockModel implements android.os.Parcelable {
+    method public int describeContents();
+    method @FloatRange(from=-0.0625F, to=0.0625f) public double getAf0();
+    method @FloatRange(from=-1.5E-8F, to=1.5E-8f) public double getAf1();
+    method @FloatRange(from=-5.56E-17F, to=5.56E-17f) public double getAf2();
+    method @FloatRange(from=-1.2E-7F, to=1.2E-7f) public double getBgdSeconds();
+    method public int getSatelliteClockType();
+    method @FloatRange(from=0.0f) public double getSisaMeters();
+    method @IntRange(from=0) public long getTimeOfClockSeconds();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel> CREATOR;
+    field public static final int TYPE_FNAV = 1; // 0x1
+    field public static final int TYPE_INAV = 2; // 0x2
+    field public static final int TYPE_UNDEFINED = 0; // 0x0
+  }
+
+  public static final class GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder {
+    ctor public GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder();
+    method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel build();
+    method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder setAf0(@FloatRange(from=-0.0625F, to=0.0625f) double);
+    method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder setAf1(@FloatRange(from=-1.5E-8F, to=1.5E-8f) double);
+    method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder setAf2(@FloatRange(from=-5.56E-17F, to=5.56E-17f) double);
+    method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder setBgdSeconds(@FloatRange(from=-1.2E-7F, to=1.2E-7f) double);
+    method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder setSatelliteClockType(int);
+    method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder setSisaMeters(@FloatRange(from=0.0f) double);
+    method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder setTimeOfClockSeconds(@IntRange(from=0) long);
+  }
+
+  public static final class GalileoSatelliteEphemeris.GalileoSvHealth implements android.os.Parcelable {
+    method public int describeContents();
+    method @IntRange(from=0, to=1) public int getDataValidityStatusE1b();
+    method @IntRange(from=0, to=1) public int getDataValidityStatusE5a();
+    method @IntRange(from=0, to=1) public int getDataValidityStatusE5b();
+    method @IntRange(from=0, to=3) public int getSignalHealthStatusE1b();
+    method @IntRange(from=0, to=3) public int getSignalHealthStatusE5a();
+    method @IntRange(from=0, to=3) public int getSignalHealthStatusE5b();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GalileoSatelliteEphemeris.GalileoSvHealth> CREATOR;
+  }
+
+  public static final class GalileoSatelliteEphemeris.GalileoSvHealth.Builder {
+    ctor public GalileoSatelliteEphemeris.GalileoSvHealth.Builder();
+    method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSvHealth build();
+    method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSvHealth.Builder setDataValidityStatusE1b(@IntRange(from=0, to=1) int);
+    method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSvHealth.Builder setDataValidityStatusE5a(@IntRange(from=0, to=1) int);
+    method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSvHealth.Builder setDataValidityStatusE5b(@IntRange(from=0, to=1) int);
+    method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSvHealth.Builder setSignalHealthStatusE1b(@IntRange(from=0, to=3) int);
+    method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSvHealth.Builder setSignalHealthStatusE5a(@IntRange(from=0, to=3) int);
+    method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSvHealth.Builder setSignalHealthStatusE5b(@IntRange(from=0, to=3) int);
+  }
+
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GlonassAlmanac implements android.os.Parcelable {
+    ctor public GlonassAlmanac(@IntRange(from=0) long, @NonNull java.util.List<android.location.GlonassAlmanac.GlonassSatelliteAlmanac>);
+    method public int describeContents();
+    method @IntRange(from=0) public long getIssueDateMillis();
+    method @NonNull public java.util.List<android.location.GlonassAlmanac.GlonassSatelliteAlmanac> getSatelliteAlmanacs();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GlonassAlmanac> CREATOR;
+  }
+
+  public static final class GlonassAlmanac.GlonassSatelliteAlmanac implements android.os.Parcelable {
+    method public int describeContents();
+    method @FloatRange(from=-0.067F, to=0.067f) public double getDeltaI();
+    method @FloatRange(from=-3600.0F, to=3600.0f) public double getDeltaT();
+    method @FloatRange(from=-0.004F, to=0.004f) public double getDeltaTDot();
+    method @FloatRange(from=0.0f, to=0.03f) public double getEccentricity();
+    method @IntRange(from=0, to=31) public int getFreqChannel();
+    method @FloatRange(from=-1.0F, to=1.0f) public double getLambda();
+    method @FloatRange(from=-1.0F, to=1.0f) public double getOmega();
+    method @IntRange(from=1, to=25) public int getSlotNumber();
+    method @IntRange(from=0, to=1) public int getSvHealth();
+    method @FloatRange(from=0.0f, to=44100.0f) public double getTLambda();
+    method @FloatRange(from=-0.0019F, to=0.0019f) public double getTau();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GlonassAlmanac.GlonassSatelliteAlmanac> CREATOR;
+  }
+
+  public static final class GlonassAlmanac.GlonassSatelliteAlmanac.Builder {
+    ctor public GlonassAlmanac.GlonassSatelliteAlmanac.Builder();
+    method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac build();
+    method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setDeltaI(@FloatRange(from=-0.067F, to=0.067f) double);
+    method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setDeltaT(@FloatRange(from=-3600.0F, to=3600.0f) double);
+    method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setDeltaTDot(@FloatRange(from=-0.004F, to=0.004f) double);
+    method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setEccentricity(@FloatRange(from=0.0f, to=0.03f) double);
+    method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setFreqChannel(@IntRange(from=0, to=31) int);
+    method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setLambda(@FloatRange(from=-1.0F, to=1.0f) double);
+    method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setOmega(@FloatRange(from=-1.0F, to=1.0f) double);
+    method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setSlotNumber(@IntRange(from=1, to=25) int);
+    method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setSvHealth(@IntRange(from=0, to=1) int);
+    method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setTLambda(@FloatRange(from=0.0f, to=44100.0f) double);
+    method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setTau(@FloatRange(from=-0.0019F, to=0.0019f) double);
+  }
+
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GlonassAssistance implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public android.location.GlonassAlmanac getAlmanac();
+    method @NonNull public java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections> getSatelliteCorrections();
+    method @NonNull public java.util.List<android.location.GlonassSatelliteEphemeris> getSatelliteEphemeris();
+    method @NonNull public java.util.List<android.location.TimeModel> getTimeModels();
+    method @Nullable public android.location.UtcModel getUtcModel();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GlonassAssistance> CREATOR;
+  }
+
+  public static final class GlonassAssistance.Builder {
+    ctor public GlonassAssistance.Builder();
+    method @NonNull public android.location.GlonassAssistance build();
+    method @NonNull public android.location.GlonassAssistance.Builder setAlmanac(@Nullable android.location.GlonassAlmanac);
+    method @NonNull public android.location.GlonassAssistance.Builder setSatelliteCorrections(@Nullable java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections>);
+    method @NonNull public android.location.GlonassAssistance.Builder setSatelliteEphemeris(@Nullable java.util.List<android.location.GlonassSatelliteEphemeris>);
+    method @NonNull public android.location.GlonassAssistance.Builder setTimeModels(@Nullable java.util.List<android.location.TimeModel>);
+    method @NonNull public android.location.GlonassAssistance.Builder setUtcModel(@Nullable android.location.UtcModel);
+  }
+
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GlonassSatelliteEphemeris implements android.os.Parcelable {
+    method public int describeContents();
+    method @IntRange(from=0, to=31) public int getAgeInDays();
+    method @FloatRange(from=0.0f) public double getFrameTimeSeconds();
+    method @IntRange(from=0, to=1) public int getHealthState();
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteClockModel getSatelliteClockModel();
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel getSatelliteOrbitModel();
+    method @IntRange(from=1, to=25) public int getSlotNumber();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GlonassSatelliteEphemeris> CREATOR;
+  }
+
+  public static final class GlonassSatelliteEphemeris.Builder {
+    ctor public GlonassSatelliteEphemeris.Builder();
+    method @NonNull public android.location.GlonassSatelliteEphemeris build();
+    method @NonNull public android.location.GlonassSatelliteEphemeris.Builder setAgeInDays(@IntRange(from=0, to=31) int);
+    method @NonNull public android.location.GlonassSatelliteEphemeris.Builder setFrameTimeSeconds(@FloatRange(from=0.0f) double);
+    method @NonNull public android.location.GlonassSatelliteEphemeris.Builder setHealthState(@IntRange(from=0, to=1) int);
+    method @NonNull public android.location.GlonassSatelliteEphemeris.Builder setSatelliteClockModel(@NonNull android.location.GlonassSatelliteEphemeris.GlonassSatelliteClockModel);
+    method @NonNull public android.location.GlonassSatelliteEphemeris.Builder setSatelliteOrbitModel(@NonNull android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel);
+    method @NonNull public android.location.GlonassSatelliteEphemeris.Builder setSlotNumber(@IntRange(from=1, to=25) int);
+  }
+
+  public static final class GlonassSatelliteEphemeris.GlonassSatelliteClockModel implements android.os.Parcelable {
+    method public int describeContents();
+    method @FloatRange(from=-0.002F, to=0.002f) public double getClockBias();
+    method @FloatRange(from=-9.32E-10F, to=9.32E-10f) public double getFrequencyBias();
+    method @IntRange(from=0xfffffff9, to=6) public int getFrequencyNumber();
+    method @IntRange(from=0) public long getTimeOfClockSeconds();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GlonassSatelliteEphemeris.GlonassSatelliteClockModel> CREATOR;
+  }
+
+  public static final class GlonassSatelliteEphemeris.GlonassSatelliteClockModel.Builder {
+    ctor public GlonassSatelliteEphemeris.GlonassSatelliteClockModel.Builder();
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteClockModel build();
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteClockModel.Builder setClockBias(@FloatRange(from=-0.002F, to=0.002f) double);
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteClockModel.Builder setFrequencyBias(@FloatRange(from=-9.32E-10F, to=9.32E-10f) double);
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteClockModel.Builder setFrequencyNumber(@IntRange(from=0xfffffff9, to=6) int);
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteClockModel.Builder setTimeOfClockSeconds(@IntRange(from=0) long);
+  }
+
+  public static final class GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel implements android.os.Parcelable {
+    method public int describeContents();
+    method @FloatRange(from=-27000.0F, to=27000.0f) public double getX();
+    method @FloatRange(from=-6.2E-9F, to=6.2E-9f) public double getXAccel();
+    method @FloatRange(from=-4.3F, to=4.3f) public double getXDot();
+    method @FloatRange(from=-27000.0F, to=27000.0f) public double getY();
+    method @FloatRange(from=-6.2E-9F, to=6.2E-9f) public double getYAccel();
+    method @FloatRange(from=-4.3F, to=4.3f) public double getYDot();
+    method @FloatRange(from=-27000.0F, to=27000.0f) public double getZ();
+    method @FloatRange(from=-6.2E-9F, to=6.2E-9f) public double getZAccel();
+    method @FloatRange(from=-4.3F, to=4.3f) public double getZDot();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel> CREATOR;
+  }
+
+  public static final class GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder {
+    ctor public GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder();
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel build();
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setX(@FloatRange(from=-27000.0F, to=27000.0f) double);
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setXAccel(@FloatRange(from=-6.2E-9F, to=6.2E-9f) double);
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setXDot(@FloatRange(from=-4.3F, to=4.3f) double);
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setY(@FloatRange(from=-27000.0F, to=27000.0f) double);
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setYAccel(@FloatRange(from=-6.2E-9F, to=6.2E-9f) double);
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setYDot(@FloatRange(from=-4.3F, to=4.3f) double);
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setZ(@FloatRange(from=-27000.0F, to=27000.0f) double);
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setZAccel(@FloatRange(from=-6.2E-9F, to=6.2E-9f) double);
+    method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setZDot(@FloatRange(from=-4.3F, to=4.3f) double);
+  }
+
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GnssAlmanac implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.List<android.location.GnssAlmanac.GnssSatelliteAlmanac> getGnssSatelliteAlmanacs();
+    method @IntRange(from=0) public int getIod();
+    method @IntRange(from=0) public long getIssueDateMillis();
+    method @IntRange(from=0, to=604800) public int getToaSeconds();
+    method @IntRange(from=0) public int getWeekNumber();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssAlmanac> CREATOR;
+  }
+
+  public static final class GnssAlmanac.Builder {
+    ctor public GnssAlmanac.Builder();
+    method @NonNull public android.location.GnssAlmanac build();
+    method @NonNull public android.location.GnssAlmanac.Builder setGnssSatelliteAlmanacs(@NonNull java.util.List<android.location.GnssAlmanac.GnssSatelliteAlmanac>);
+    method @NonNull public android.location.GnssAlmanac.Builder setIod(@IntRange(from=0) int);
+    method @NonNull public android.location.GnssAlmanac.Builder setIssueDateMillis(@IntRange(from=0) long);
+    method @NonNull public android.location.GnssAlmanac.Builder setToaSeconds(@IntRange(from=0, to=604800) int);
+    method @NonNull public android.location.GnssAlmanac.Builder setWeekNumber(@IntRange(from=0) int);
+  }
+
+  public static final class GnssAlmanac.GnssSatelliteAlmanac implements android.os.Parcelable {
+    method public int describeContents();
+    method @FloatRange(from=-0.0625F, to=0.0625f) public double getAf0();
+    method @FloatRange(from=-1.5E-8F, to=1.5E-8f) public double getAf1();
+    method @FloatRange(from=0.0f) public double getEccentricity();
+    method @FloatRange(from=-1.0F, to=1.0f) public double getInclination();
+    method @FloatRange(from=-1.0F, to=1.0f) public double getM0();
+    method @FloatRange(from=-1.0F, to=1.0f) public double getOmega();
+    method @FloatRange(from=-1.0F, to=1.0f) public double getOmega0();
+    method @FloatRange(from=-1.0F, to=1.0f) public double getOmegaDot();
+    method @FloatRange(from=0.0f, to=8192.0f) public double getRootA();
+    method @IntRange(from=0) public int getSvHealth();
+    method @IntRange(from=1) public int getSvid();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssAlmanac.GnssSatelliteAlmanac> CREATOR;
+  }
+
+  public static final class GnssAlmanac.GnssSatelliteAlmanac.Builder {
+    ctor public GnssAlmanac.GnssSatelliteAlmanac.Builder();
+    method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac build();
+    method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setAf0(@FloatRange(from=-0.0625F, to=0.0625f) double);
+    method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setAf1(@FloatRange(from=-1.5E-8F, to=1.5E-8f) double);
+    method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setEccentricity(@FloatRange(from=0.0f) double);
+    method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setInclination(@FloatRange(from=-1.0F, to=1.0f) double);
+    method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setM0(@FloatRange(from=-1.0F, to=1.0f) double);
+    method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setOmega(@FloatRange(from=-1.0F, to=1.0f) double);
+    method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setOmega0(@FloatRange(from=-1.0F, to=1.0f) double);
+    method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setOmegaDot(@FloatRange(from=-1.0F, to=1.0f) double);
+    method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setRootA(@FloatRange(from=0.0f, to=8192.0f) double);
+    method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setSvHealth(@IntRange(from=0) int);
+    method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setSvid(@IntRange(from=1) int);
+  }
+
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GnssAssistance implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public android.location.BeidouAssistance getBeidouAssistance();
+    method @Nullable public android.location.GalileoAssistance getGalileoAssistance();
+    method @Nullable public android.location.GlonassAssistance getGlonassAssistance();
+    method @Nullable public android.location.GpsAssistance getGpsAssistance();
+    method @Nullable public android.location.QzssAssistance getQzssAssistance();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssAssistance> CREATOR;
+  }
+
+  public static final class GnssAssistance.Builder {
+    ctor public GnssAssistance.Builder();
+    method @NonNull public android.location.GnssAssistance build();
+    method @NonNull public android.location.GnssAssistance.Builder setBeidouAssistance(@Nullable android.location.BeidouAssistance);
+    method @NonNull public android.location.GnssAssistance.Builder setGalileoAssistance(@Nullable android.location.GalileoAssistance);
+    method @NonNull public android.location.GnssAssistance.Builder setGlonassAssistance(@Nullable android.location.GlonassAssistance);
+    method @NonNull public android.location.GnssAssistance.Builder setGpsAssistance(@Nullable android.location.GpsAssistance);
+    method @NonNull public android.location.GnssAssistance.Builder setQzssAssistance(@Nullable android.location.QzssAssistance);
+  }
+
+  public static final class GnssAssistance.GnssSatelliteCorrections implements android.os.Parcelable {
+    ctor public GnssAssistance.GnssSatelliteCorrections(@IntRange(from=1, to=206) int, @NonNull java.util.List<android.location.IonosphericCorrection>);
+    method public int describeContents();
+    method @NonNull public java.util.List<android.location.IonosphericCorrection> getIonosphericCorrections();
+    method @IntRange(from=1, to=206) public int getSvid();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssAssistance.GnssSatelliteCorrections> CREATOR;
+  }
+
   public final class GnssCapabilities implements android.os.Parcelable {
     method @Deprecated public boolean hasMeasurementCorrectionsReflectingPane();
     method @Deprecated public boolean hasNavMessages();
     method @Deprecated public boolean hasSatelliteBlacklist();
   }
 
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GnssCorrectionComponent implements android.os.Parcelable {
+    ctor public GnssCorrectionComponent(@NonNull String, @NonNull android.location.GnssCorrectionComponent.GnssInterval, @NonNull android.location.GnssCorrectionComponent.PseudorangeCorrection);
+    method public int describeContents();
+    method @NonNull public android.location.GnssCorrectionComponent.PseudorangeCorrection getPseudorangeCorrection();
+    method @NonNull public String getSourceKey();
+    method @NonNull public android.location.GnssCorrectionComponent.GnssInterval getValidityInterval();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssCorrectionComponent> CREATOR;
+  }
+
+  public static final class GnssCorrectionComponent.GnssInterval implements android.os.Parcelable {
+    ctor public GnssCorrectionComponent.GnssInterval(@IntRange(from=0) long, @IntRange(from=0) long);
+    method public int describeContents();
+    method @IntRange(from=0) public long getEndMillisSinceGpsEpoch();
+    method @IntRange(from=0) public long getStartMillisSinceGpsEpoch();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssCorrectionComponent.GnssInterval> CREATOR;
+  }
+
+  public static final class GnssCorrectionComponent.PseudorangeCorrection implements android.os.Parcelable {
+    ctor public GnssCorrectionComponent.PseudorangeCorrection(double, double, double);
+    method public int describeContents();
+    method public double getCorrectionMeters();
+    method public double getCorrectionRateMetersPerSecond();
+    method @FloatRange(from=0.0f) public double getCorrectionUncertaintyMeters();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssCorrectionComponent.PseudorangeCorrection> CREATOR;
+  }
+
   public final class GnssExcessPathInfo implements android.os.Parcelable {
     method public int describeContents();
     method @FloatRange(from=0.0f) public float getAttenuationDb();
@@ -193,6 +661,33 @@
     method @NonNull public android.location.GnssSingleSatCorrection.Builder setSatelliteId(@IntRange(from=0) int);
   }
 
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GpsAssistance implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public android.location.GnssAlmanac getAlmanac();
+    method @Nullable public android.location.KlobucharIonosphericModel getIonosphericModel();
+    method @Nullable public android.location.LeapSecondsModel getLeapSecondsModel();
+    method @NonNull public java.util.List<android.location.RealTimeIntegrityModel> getRealTimeIntegrityModels();
+    method @NonNull public java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections> getSatelliteCorrections();
+    method @NonNull public java.util.List<android.location.GpsSatelliteEphemeris> getSatelliteEphemeris();
+    method @NonNull public java.util.List<android.location.TimeModel> getTimeModels();
+    method @Nullable public android.location.UtcModel getUtcModel();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GpsAssistance> CREATOR;
+  }
+
+  public static final class GpsAssistance.Builder {
+    ctor public GpsAssistance.Builder();
+    method @NonNull public android.location.GpsAssistance build();
+    method @NonNull public android.location.GpsAssistance.Builder setAlmanac(@Nullable android.location.GnssAlmanac);
+    method @NonNull public android.location.GpsAssistance.Builder setIonosphericModel(@Nullable android.location.KlobucharIonosphericModel);
+    method @NonNull public android.location.GpsAssistance.Builder setLeapSecondsModel(@Nullable android.location.LeapSecondsModel);
+    method @NonNull public android.location.GpsAssistance.Builder setRealTimeIntegrityModels(@Nullable java.util.List<android.location.RealTimeIntegrityModel>);
+    method @NonNull public android.location.GpsAssistance.Builder setSatelliteCorrections(@Nullable java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections>);
+    method @NonNull public android.location.GpsAssistance.Builder setSatelliteEphemeris(@Nullable java.util.List<android.location.GpsSatelliteEphemeris>);
+    method @NonNull public android.location.GpsAssistance.Builder setTimeModels(@Nullable java.util.List<android.location.TimeModel>);
+    method @NonNull public android.location.GpsAssistance.Builder setUtcModel(@Nullable android.location.UtcModel);
+  }
+
   @Deprecated public class GpsClock implements android.os.Parcelable {
     method @Deprecated public int describeContents();
     method @Deprecated public double getBiasInNs();
@@ -418,6 +913,174 @@
     method @Deprecated public void onStatusChanged(int);
   }
 
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GpsSatelliteEphemeris implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsL2Params getGpsL2Params();
+    method @IntRange(from=1, to=32) public int getPrn();
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel getSatelliteClockModel();
+    method @NonNull public android.location.SatelliteEphemerisTime getSatelliteEphemerisTime();
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteHealth getSatelliteHealth();
+    method @NonNull public android.location.KeplerianOrbitModel getSatelliteOrbitModel();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GpsSatelliteEphemeris> CREATOR;
+  }
+
+  public static final class GpsSatelliteEphemeris.Builder {
+    ctor public GpsSatelliteEphemeris.Builder();
+    method @NonNull public android.location.GpsSatelliteEphemeris build();
+    method @NonNull public android.location.GpsSatelliteEphemeris.Builder setGpsL2Params(@NonNull android.location.GpsSatelliteEphemeris.GpsL2Params);
+    method @NonNull public android.location.GpsSatelliteEphemeris.Builder setPrn(@IntRange(from=1, to=32) int);
+    method @NonNull public android.location.GpsSatelliteEphemeris.Builder setSatelliteClockModel(@NonNull android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel);
+    method @NonNull public android.location.GpsSatelliteEphemeris.Builder setSatelliteEphemerisTime(@NonNull android.location.SatelliteEphemerisTime);
+    method @NonNull public android.location.GpsSatelliteEphemeris.Builder setSatelliteHealth(@NonNull android.location.GpsSatelliteEphemeris.GpsSatelliteHealth);
+    method @NonNull public android.location.GpsSatelliteEphemeris.Builder setSatelliteOrbitModel(@NonNull android.location.KeplerianOrbitModel);
+  }
+
+  public static final class GpsSatelliteEphemeris.GpsL2Params implements android.os.Parcelable {
+    method public int describeContents();
+    method @IntRange(from=0, to=3) public int getL2Code();
+    method @IntRange(from=0, to=1) public int getL2Flag();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GpsSatelliteEphemeris.GpsL2Params> CREATOR;
+  }
+
+  public static final class GpsSatelliteEphemeris.GpsL2Params.Builder {
+    ctor public GpsSatelliteEphemeris.GpsL2Params.Builder();
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsL2Params build();
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsL2Params.Builder setL2Code(@IntRange(from=0, to=3) int);
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsL2Params.Builder setL2Flag(@IntRange(from=0, to=1) int);
+  }
+
+  public static final class GpsSatelliteEphemeris.GpsSatelliteClockModel implements android.os.Parcelable {
+    method public int describeContents();
+    method @FloatRange(from=-0.00977F, to=0.00977f) public double getAf0();
+    method @FloatRange(from=-3.73E-9F, to=3.73E-9f) public double getAf1();
+    method @FloatRange(from=-3.56E-15F, to=3.56E-15f) public double getAf2();
+    method @IntRange(from=0, to=1023) public int getIodc();
+    method @FloatRange(from=-5.97E-8F, to=5.97E-8f) public double getTgd();
+    method @IntRange(from=0) public long getTimeOfClockSeconds();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel> CREATOR;
+  }
+
+  public static final class GpsSatelliteEphemeris.GpsSatelliteClockModel.Builder {
+    ctor public GpsSatelliteEphemeris.GpsSatelliteClockModel.Builder();
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel build();
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel.Builder setAf0(@FloatRange(from=-0.00977F, to=0.00977f) double);
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel.Builder setAf1(@FloatRange(from=-3.73E-9F, to=3.73E-9f) double);
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel.Builder setAf2(@FloatRange(from=-3.56E-15F, to=3.56E-15f) double);
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel.Builder setIodc(@IntRange(from=0, to=1023) int);
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel.Builder setTgd(@FloatRange(from=-5.97E-8F, to=5.97E-8f) double);
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel.Builder setTimeOfClockSeconds(@IntRange(from=0) long);
+  }
+
+  public static final class GpsSatelliteEphemeris.GpsSatelliteHealth implements android.os.Parcelable {
+    method public int describeContents();
+    method @FloatRange(from=0.0f) public double getFitInt();
+    method @FloatRange(from=0.0f, to=8192.0f) public double getSvAccur();
+    method @IntRange(from=0, to=63) public int getSvHealth();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.GpsSatelliteEphemeris.GpsSatelliteHealth> CREATOR;
+  }
+
+  public static final class GpsSatelliteEphemeris.GpsSatelliteHealth.Builder {
+    ctor public GpsSatelliteEphemeris.GpsSatelliteHealth.Builder();
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteHealth build();
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteHealth.Builder setFitInt(@FloatRange(from=0.0f) double);
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteHealth.Builder setSvAccur(@FloatRange(from=0.0f, to=8192.0f) double);
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteHealth.Builder setSvHealth(@IntRange(from=0, to=63) int);
+  }
+
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class IonosphericCorrection implements android.os.Parcelable {
+    ctor public IonosphericCorrection(@IntRange(from=0) long, @NonNull android.location.GnssCorrectionComponent);
+    method public int describeContents();
+    method @IntRange(from=0) public long getCarrierFrequencyHz();
+    method @NonNull public android.location.GnssCorrectionComponent getIonosphericCorrection();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.IonosphericCorrection> CREATOR;
+  }
+
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class KeplerianOrbitModel implements android.os.Parcelable {
+    method public int describeContents();
+    method @FloatRange(from=-1.18E-8F, to=1.18E-8f) public double getDeltaN();
+    method @FloatRange(from=0.0f, to=0.5f) public double getEccentricity();
+    method @FloatRange(from=-3.15F, to=3.15f) public double getI0();
+    method @FloatRange(from=-2.94E-9F, to=2.94E-9f) public double getIDot();
+    method @FloatRange(from=-3.15F, to=3.15f) public double getM0();
+    method @FloatRange(from=-3.15F, to=3.15f) public double getOmega();
+    method @FloatRange(from=-3.15F, to=3.15f) public double getOmega0();
+    method @FloatRange(from=-3.1E-6F, to=3.1E-6f) public double getOmegaDot();
+    method @FloatRange(from=0.0f, to=8192.0f) public double getRootA();
+    method @NonNull public android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation getSecondOrderHarmonicPerturbation();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.KeplerianOrbitModel> CREATOR;
+  }
+
+  public static final class KeplerianOrbitModel.Builder {
+    ctor public KeplerianOrbitModel.Builder();
+    method @NonNull public android.location.KeplerianOrbitModel build();
+    method @NonNull public android.location.KeplerianOrbitModel.Builder setDeltaN(@FloatRange(from=-1.18E-8F, to=1.18E-8f) double);
+    method @NonNull public android.location.KeplerianOrbitModel.Builder setEccentricity(@FloatRange(from=0.0f, to=0.5f) double);
+    method @NonNull public android.location.KeplerianOrbitModel.Builder setI0(@FloatRange(from=-3.15F, to=3.15f) double);
+    method @NonNull public android.location.KeplerianOrbitModel.Builder setIDot(@FloatRange(from=-2.94E-9F, to=2.94E-9f) double);
+    method @NonNull public android.location.KeplerianOrbitModel.Builder setM0(@FloatRange(from=-3.15F, to=3.15f) double);
+    method @NonNull public android.location.KeplerianOrbitModel.Builder setOmega(@FloatRange(from=-3.15F, to=3.15f) double);
+    method @NonNull public android.location.KeplerianOrbitModel.Builder setOmega0(@FloatRange(from=-3.15F, to=3.15f) double);
+    method @NonNull public android.location.KeplerianOrbitModel.Builder setOmegaDot(@FloatRange(from=-3.1E-6F, to=3.1E-6f) double);
+    method @NonNull public android.location.KeplerianOrbitModel.Builder setRootA(@FloatRange(from=0.0f, to=8192.0f) double);
+    method @NonNull public android.location.KeplerianOrbitModel.Builder setSecondOrderHarmonicPerturbation(@NonNull android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation);
+  }
+
+  public static final class KeplerianOrbitModel.SecondOrderHarmonicPerturbation implements android.os.Parcelable {
+    method public int describeContents();
+    method @FloatRange(from=-6.11E-5F, to=6.11E-5f) public double getCic();
+    method @FloatRange(from=-6.11E-5F, to=6.11E-5f) public double getCis();
+    method @FloatRange(from=-2048.0F, to=2048.0f) public double getCrc();
+    method @FloatRange(from=-2048.0F, to=2048.0f) public double getCrs();
+    method @FloatRange(from=-6.11E-5F, to=6.11E-5f) public double getCuc();
+    method @FloatRange(from=-6.11E-5F, to=6.11E-5f) public double getCus();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation> CREATOR;
+  }
+
+  public static final class KeplerianOrbitModel.SecondOrderHarmonicPerturbation.Builder {
+    ctor public KeplerianOrbitModel.SecondOrderHarmonicPerturbation.Builder();
+    method @NonNull public android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation build();
+    method @NonNull public android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation.Builder setCic(@FloatRange(from=-6.11E-5F, to=6.11E-5f) double);
+    method @NonNull public android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation.Builder setCis(@FloatRange(from=-6.11E-5F, to=6.11E-5f) double);
+    method @NonNull public android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation.Builder setCrc(@FloatRange(from=-2048.0F, to=2048.0f) double);
+    method @NonNull public android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation.Builder setCrs(@FloatRange(from=-2048.0F, to=2048.0f) double);
+    method @NonNull public android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation.Builder setCuc(@FloatRange(from=-6.11E-5F, to=6.11E-5f) double);
+    method @NonNull public android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation.Builder setCus(@FloatRange(from=-6.11E-5F, to=6.11E-5f) double);
+  }
+
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class KlobucharIonosphericModel implements android.os.Parcelable {
+    method public int describeContents();
+    method @FloatRange(from=-1.193E-7F, to=1.193E-7f) public double getAlpha0();
+    method @FloatRange(from=-9.54E-7F, to=9.54E-7f) public double getAlpha1();
+    method @FloatRange(from=-7.63E-6F, to=7.63E-6f) public double getAlpha2();
+    method @FloatRange(from=-7.63E-6F, to=7.63E-6f) public double getAlpha3();
+    method @FloatRange(from=-262144.0F, to=262144.0f) public double getBeta0();
+    method @FloatRange(from=-2097152.0F, to=2097152.0f) public double getBeta1();
+    method @FloatRange(from=-8388608.0F, to=8388608.0f) public double getBeta2();
+    method @FloatRange(from=-8388608.0F, to=8388608.0f) public double getBeta3();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.KlobucharIonosphericModel> CREATOR;
+  }
+
+  public static final class KlobucharIonosphericModel.Builder {
+    ctor public KlobucharIonosphericModel.Builder();
+    method @NonNull public android.location.KlobucharIonosphericModel build();
+    method @NonNull public android.location.KlobucharIonosphericModel.Builder setAlpha0(@FloatRange(from=-1.193E-7F, to=1.193E-7f) double);
+    method @NonNull public android.location.KlobucharIonosphericModel.Builder setAlpha1(@FloatRange(from=-9.54E-7F, to=9.54E-7f) double);
+    method @NonNull public android.location.KlobucharIonosphericModel.Builder setAlpha2(@FloatRange(from=-7.63E-6F, to=7.63E-6f) double);
+    method @NonNull public android.location.KlobucharIonosphericModel.Builder setAlpha3(@FloatRange(from=-7.63E-6F, to=7.63E-6f) double);
+    method @NonNull public android.location.KlobucharIonosphericModel.Builder setBeta0(@FloatRange(from=-262144.0F, to=262144.0f) double);
+    method @NonNull public android.location.KlobucharIonosphericModel.Builder setBeta1(@FloatRange(from=-2097152.0F, to=2097152.0f) double);
+    method @NonNull public android.location.KlobucharIonosphericModel.Builder setBeta2(@FloatRange(from=-8388608.0F, to=8388608.0f) double);
+    method @NonNull public android.location.KlobucharIonosphericModel.Builder setBeta3(@FloatRange(from=-8388608.0F, to=8388608.0f) double);
+  }
+
   public final class LastLocationRequest implements android.os.Parcelable {
     method public int describeContents();
     method public boolean isAdasGnssBypass();
@@ -436,6 +1099,25 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_BYPASS) public android.location.LastLocationRequest.Builder setLocationSettingsIgnored(boolean);
   }
 
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class LeapSecondsModel implements android.os.Parcelable {
+    method public int describeContents();
+    method @IntRange(from=0) public int getDayNumberLeapSecondsFuture();
+    method @IntRange(from=0) public int getLeapSeconds();
+    method @IntRange(from=0) public int getLeapSecondsFuture();
+    method @IntRange(from=0) public int getWeekNumberLeapSecondsFuture();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.LeapSecondsModel> CREATOR;
+  }
+
+  public static final class LeapSecondsModel.Builder {
+    ctor public LeapSecondsModel.Builder();
+    method @NonNull public android.location.LeapSecondsModel build();
+    method @NonNull public android.location.LeapSecondsModel.Builder setDayNumberLeapSecondsFuture(@IntRange(from=0) int);
+    method @NonNull public android.location.LeapSecondsModel.Builder setLeapSeconds(@IntRange(from=0) int);
+    method @NonNull public android.location.LeapSecondsModel.Builder setLeapSecondsFuture(@IntRange(from=0) int);
+    method @NonNull public android.location.LeapSecondsModel.Builder setWeekNumberLeapSecondsFuture(@IntRange(from=0) int);
+  }
+
   public class LocationManager {
     method @Deprecated @FlaggedApi("android.location.flags.deprecate_provider_request_apis") @RequiresPermission(allOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.INTERACT_ACROSS_USERS}) public void addProviderRequestChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.location.provider.ProviderRequest.ChangedListener);
     method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void flushGnssBatch();
@@ -513,6 +1195,98 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.location.LocationRequest.Builder setWorkSource(@Nullable android.os.WorkSource);
   }
 
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class QzssAssistance implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public android.location.GnssAlmanac getAlmanac();
+    method @Nullable public android.location.KlobucharIonosphericModel getIonosphericModel();
+    method @Nullable public android.location.LeapSecondsModel getLeapSecondsModel();
+    method @NonNull public java.util.List<android.location.RealTimeIntegrityModel> getRealTimeIntegrityModels();
+    method @NonNull public java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections> getSatelliteCorrections();
+    method @NonNull public java.util.List<android.location.QzssSatelliteEphemeris> getSatelliteEphemeris();
+    method @NonNull public java.util.List<android.location.TimeModel> getTimeModels();
+    method @Nullable public android.location.UtcModel getUtcModel();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.QzssAssistance> CREATOR;
+  }
+
+  public static final class QzssAssistance.Builder {
+    ctor public QzssAssistance.Builder();
+    method @NonNull public android.location.QzssAssistance build();
+    method @NonNull public android.location.QzssAssistance.Builder setAlmanac(@Nullable android.location.GnssAlmanac);
+    method @NonNull public android.location.QzssAssistance.Builder setIonosphericModel(@Nullable android.location.KlobucharIonosphericModel);
+    method @NonNull public android.location.QzssAssistance.Builder setLeapSecondsModel(@Nullable android.location.LeapSecondsModel);
+    method @NonNull public android.location.QzssAssistance.Builder setRealTimeIntegrityModels(@Nullable java.util.List<android.location.RealTimeIntegrityModel>);
+    method @NonNull public android.location.QzssAssistance.Builder setSatelliteCorrections(@Nullable java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections>);
+    method @NonNull public android.location.QzssAssistance.Builder setSatelliteEphemeris(@Nullable java.util.List<android.location.QzssSatelliteEphemeris>);
+    method @NonNull public android.location.QzssAssistance.Builder setTimeModels(@Nullable java.util.List<android.location.TimeModel>);
+    method @NonNull public android.location.QzssAssistance.Builder setUtcModel(@Nullable android.location.UtcModel);
+  }
+
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class QzssSatelliteEphemeris implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsL2Params getGpsL2Params();
+    method @IntRange(from=183, to=206) public int getPrn();
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel getSatelliteClockModel();
+    method @NonNull public android.location.SatelliteEphemerisTime getSatelliteEphemerisTime();
+    method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteHealth getSatelliteHealth();
+    method @NonNull public android.location.KeplerianOrbitModel getSatelliteOrbitModel();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.QzssSatelliteEphemeris> CREATOR;
+  }
+
+  public static final class QzssSatelliteEphemeris.Builder {
+    ctor public QzssSatelliteEphemeris.Builder();
+    method @NonNull public android.location.QzssSatelliteEphemeris build();
+    method @NonNull public android.location.QzssSatelliteEphemeris.Builder setGpsL2Params(@NonNull android.location.GpsSatelliteEphemeris.GpsL2Params);
+    method @NonNull public android.location.QzssSatelliteEphemeris.Builder setPrn(@IntRange(from=183, to=206) int);
+    method @NonNull public android.location.QzssSatelliteEphemeris.Builder setSatelliteClockModel(@NonNull android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel);
+    method @NonNull public android.location.QzssSatelliteEphemeris.Builder setSatelliteEphemerisTime(@NonNull android.location.SatelliteEphemerisTime);
+    method @NonNull public android.location.QzssSatelliteEphemeris.Builder setSatelliteHealth(@NonNull android.location.GpsSatelliteEphemeris.GpsSatelliteHealth);
+    method @NonNull public android.location.QzssSatelliteEphemeris.Builder setSatelliteOrbitModel(@NonNull android.location.KeplerianOrbitModel);
+  }
+
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class RealTimeIntegrityModel implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public String getAdvisoryNumber();
+    method @NonNull public String getAdvisoryType();
+    method @IntRange(from=0) public long getEndDateSeconds();
+    method @IntRange(from=0) public long getPublishDateSeconds();
+    method @IntRange(from=0) public long getStartDateSeconds();
+    method @IntRange(from=1, to=206) public int getSvid();
+    method public boolean isUsable();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.RealTimeIntegrityModel> CREATOR;
+  }
+
+  public static final class RealTimeIntegrityModel.Builder {
+    ctor public RealTimeIntegrityModel.Builder();
+    method @NonNull public android.location.RealTimeIntegrityModel build();
+    method @NonNull public android.location.RealTimeIntegrityModel.Builder setAdvisoryNumber(@NonNull String);
+    method @NonNull public android.location.RealTimeIntegrityModel.Builder setAdvisoryType(@NonNull String);
+    method @NonNull public android.location.RealTimeIntegrityModel.Builder setEndDateSeconds(@IntRange(from=0) long);
+    method @NonNull public android.location.RealTimeIntegrityModel.Builder setPublishDateSeconds(@IntRange(from=0) long);
+    method @NonNull public android.location.RealTimeIntegrityModel.Builder setStartDateSeconds(@IntRange(from=0) long);
+    method @NonNull public android.location.RealTimeIntegrityModel.Builder setSvid(@IntRange(from=1, to=206) int);
+    method @NonNull public android.location.RealTimeIntegrityModel.Builder setUsable(boolean);
+  }
+
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class SatelliteEphemerisTime implements android.os.Parcelable {
+    method public int describeContents();
+    method @IntRange(from=0, to=1023) public int getIode();
+    method @IntRange(from=0, to=604799) public int getToeSeconds();
+    method @IntRange(from=0) public int getWeekNumber();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.SatelliteEphemerisTime> CREATOR;
+  }
+
+  public static final class SatelliteEphemerisTime.Builder {
+    ctor public SatelliteEphemerisTime.Builder();
+    method @NonNull public android.location.SatelliteEphemerisTime build();
+    method @NonNull public android.location.SatelliteEphemerisTime.Builder setIode(@IntRange(from=0, to=1023) int);
+    method @NonNull public android.location.SatelliteEphemerisTime.Builder setToeSeconds(@IntRange(from=0, to=604799) int);
+    method @NonNull public android.location.SatelliteEphemerisTime.Builder setWeekNumber(@IntRange(from=0) int);
+  }
+
   public final class SatellitePvt implements android.os.Parcelable {
     method public int describeContents();
     method @Nullable public android.location.SatellitePvt.ClockInfo getClockInfo();
@@ -587,6 +1361,46 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.location.SatellitePvt.VelocityEcef> CREATOR;
   }
 
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class TimeModel implements android.os.Parcelable {
+    method public int describeContents();
+    method @FloatRange(from=-1.0F, to=1.0f) public double getA0();
+    method @FloatRange(from=-3.28E-6F, to=3.28E-6f) public double getA1();
+    method @IntRange(from=0, to=604800) public int getTimeOfWeek();
+    method public int getToGnss();
+    method @IntRange(from=0) public int getWeekNumber();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.TimeModel> CREATOR;
+  }
+
+  public static final class TimeModel.Builder {
+    ctor public TimeModel.Builder();
+    method @NonNull public android.location.TimeModel build();
+    method @NonNull public android.location.TimeModel.Builder setA0(@FloatRange(from=-1.0F, to=1.0f) double);
+    method @NonNull public android.location.TimeModel.Builder setA1(@FloatRange(from=-3.28E-6F, to=3.28E-6f) double);
+    method @NonNull public android.location.TimeModel.Builder setTimeOfWeek(@IntRange(from=0, to=604800) int);
+    method @NonNull public android.location.TimeModel.Builder setToGnss(int);
+    method @NonNull public android.location.TimeModel.Builder setWeekNumber(@IntRange(from=0) int);
+  }
+
+  @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class UtcModel implements android.os.Parcelable {
+    method public int describeContents();
+    method @FloatRange(from=-2.0F, to=2.0f) public double getA0();
+    method @FloatRange(from=-7.45E-9F, to=7.45E-9f) public double getA1();
+    method @IntRange(from=0, to=604800) public int getTimeOfWeek();
+    method @IntRange(from=0) public int getWeekNumber();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.UtcModel> CREATOR;
+  }
+
+  public static final class UtcModel.Builder {
+    ctor public UtcModel.Builder();
+    method @NonNull public android.location.UtcModel build();
+    method @NonNull public android.location.UtcModel.Builder setA0(@FloatRange(from=-2.0F, to=2.0f) double);
+    method @NonNull public android.location.UtcModel.Builder setA1(@FloatRange(from=-7.45E-9F, to=7.45E-9f) double);
+    method @NonNull public android.location.UtcModel.Builder setTimeOfWeek(@IntRange(from=0, to=604800) int);
+    method @NonNull public android.location.UtcModel.Builder setWeekNumber(@IntRange(from=0) int);
+  }
+
 }
 
 package android.location.provider {
diff --git a/location/java/android/location/BeidouAssistance.java b/location/java/android/location/BeidouAssistance.java
new file mode 100644
index 0000000..f55249e6
--- /dev/null
+++ b/location/java/android/location/BeidouAssistance.java
@@ -0,0 +1,283 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.location.GnssAssistance.GnssSatelliteCorrections;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class contains Beidou assistance.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class BeidouAssistance implements Parcelable {
+
+    /** The Beidou almanac. */
+    @Nullable private final GnssAlmanac mAlmanac;
+
+    /** The Klobuchar ionospheric model. */
+    @Nullable private final KlobucharIonosphericModel mIonosphericModel;
+
+    /** The UTC model. */
+    @Nullable private final UtcModel mUtcModel;
+
+    /** The leap seconds model. */
+    @Nullable private final LeapSecondsModel mLeapSecondsModel;
+
+    /** The list of time models. */
+    @NonNull private final List<TimeModel> mTimeModels;
+
+    /** The list of Beidou ephemeris. */
+    @NonNull private final List<BeidouSatelliteEphemeris> mSatelliteEphemeris;
+
+    /** The list of real time integrity models. */
+    @NonNull private final List<RealTimeIntegrityModel> mRealTimeIntegrityModels;
+
+    /** The list of Beidou satellite corrections. */
+    @NonNull private final List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+    private BeidouAssistance(Builder builder) {
+        mAlmanac = builder.mAlmanac;
+        mIonosphericModel = builder.mIonosphericModel;
+        mUtcModel = builder.mUtcModel;
+        mLeapSecondsModel = builder.mLeapSecondsModel;
+        if (builder.mTimeModels != null) {
+            mTimeModels = Collections.unmodifiableList(new ArrayList<>(builder.mTimeModels));
+        } else {
+            mTimeModels = new ArrayList<>();
+        }
+        if (builder.mSatelliteEphemeris != null) {
+            mSatelliteEphemeris =
+                    Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteEphemeris));
+        } else {
+            mSatelliteEphemeris = new ArrayList<>();
+        }
+        if (builder.mRealTimeIntegrityModels != null) {
+            mRealTimeIntegrityModels =
+                    Collections.unmodifiableList(new ArrayList<>(builder.mRealTimeIntegrityModels));
+        } else {
+            mRealTimeIntegrityModels = new ArrayList<>();
+        }
+        if (builder.mSatelliteCorrections != null) {
+            mSatelliteCorrections =
+                    Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteCorrections));
+        } else {
+            mSatelliteCorrections = new ArrayList<>();
+        }
+    }
+
+    /** Returns the Beidou almanac. */
+    @Nullable
+    public GnssAlmanac getAlmanac() {
+        return mAlmanac;
+    }
+
+    /** Returns the Klobuchar ionospheric model. */
+    @Nullable
+    public KlobucharIonosphericModel getIonosphericModel() {
+        return mIonosphericModel;
+    }
+
+    /** Returns the UTC model. */
+    @Nullable
+    public UtcModel getUtcModel() {
+        return mUtcModel;
+    }
+
+    /** Returns the leap seconds model. */
+    @Nullable
+    public LeapSecondsModel getLeapSecondsModel() {
+        return mLeapSecondsModel;
+    }
+
+    /** Returns the list of time models. */
+    @NonNull
+    public List<TimeModel> getTimeModels() {
+        return mTimeModels;
+    }
+
+    /** Returns the list ofBeidou ephemeris. */
+    @NonNull
+    public List<BeidouSatelliteEphemeris> getSatelliteEphemeris() {
+        return mSatelliteEphemeris;
+    }
+
+    /** Returns the list of real time integrity models. */
+    @NonNull
+    public List<RealTimeIntegrityModel> getRealTimeIntegrityModels() {
+        return mRealTimeIntegrityModels;
+    }
+
+    /** Returns the list of Beidou satellite corrections. */
+    @NonNull
+    public List<GnssSatelliteCorrections> getSatelliteCorrections() {
+        return mSatelliteCorrections;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("BeidouAssistance[");
+        builder.append("almanac = ").append(mAlmanac);
+        builder.append(", ionosphericModel = ").append(mIonosphericModel);
+        builder.append(", utcModel = ").append(mUtcModel);
+        builder.append(", leapSecondsModel = ").append(mLeapSecondsModel);
+        builder.append(", timeModels = ").append(mTimeModels);
+        builder.append(", satelliteEphemeris = ").append(mSatelliteEphemeris);
+        builder.append(", realTimeIntegrityModels = ").append(mRealTimeIntegrityModels);
+        builder.append(", satelliteCorrections = ").append(mSatelliteCorrections);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeTypedObject(mAlmanac, flags);
+        dest.writeTypedObject(mIonosphericModel, flags);
+        dest.writeTypedObject(mUtcModel, flags);
+        dest.writeTypedObject(mLeapSecondsModel, flags);
+        dest.writeTypedList(mTimeModels);
+        dest.writeTypedList(mSatelliteEphemeris);
+        dest.writeTypedList(mRealTimeIntegrityModels);
+        dest.writeTypedList(mSatelliteCorrections);
+    }
+
+    public static final @android.annotation.NonNull Creator<BeidouAssistance> CREATOR =
+            new Creator<BeidouAssistance>() {
+                @Override
+                public BeidouAssistance createFromParcel(Parcel in) {
+                    return new BeidouAssistance.Builder()
+                            .setAlmanac(in.readTypedObject(GnssAlmanac.CREATOR))
+                            .setIonosphericModel(
+                                    in.readTypedObject(KlobucharIonosphericModel.CREATOR))
+                            .setUtcModel(in.readTypedObject(UtcModel.CREATOR))
+                            .setLeapSecondsModel(in.readTypedObject(LeapSecondsModel.CREATOR))
+                            .setTimeModels(in.createTypedArrayList(TimeModel.CREATOR))
+                            .setSatelliteEphemeris(
+                                    in.createTypedArrayList(BeidouSatelliteEphemeris.CREATOR))
+                            .setRealTimeIntegrityModels(
+                                    in.createTypedArrayList(RealTimeIntegrityModel.CREATOR))
+                            .setSatelliteCorrections(
+                                    in.createTypedArrayList(GnssSatelliteCorrections.CREATOR))
+                            .build();
+                }
+
+                @Override
+                public BeidouAssistance[] newArray(int size) {
+                    return new BeidouAssistance[size];
+                }
+            };
+
+    /** Builder for {@link BeidouAssistance}. */
+    public static final class Builder {
+        private GnssAlmanac mAlmanac;
+        private KlobucharIonosphericModel mIonosphericModel;
+        private UtcModel mUtcModel;
+        private LeapSecondsModel mLeapSecondsModel;
+        private List<TimeModel> mTimeModels;
+        private List<BeidouSatelliteEphemeris> mSatelliteEphemeris;
+        private List<RealTimeIntegrityModel> mRealTimeIntegrityModels;
+        private List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+        /** Sets the Beidou almanac. */
+        @NonNull
+        public Builder setAlmanac(@Nullable GnssAlmanac almanac) {
+            mAlmanac = almanac;
+            return this;
+        }
+
+        /** Sets the Klobuchar ionospheric model. */
+        @NonNull
+        public Builder setIonosphericModel(@Nullable KlobucharIonosphericModel ionosphericModel) {
+            mIonosphericModel = ionosphericModel;
+            return this;
+        }
+
+        /** Sets the UTC model. */
+        @NonNull
+        public Builder setUtcModel(@Nullable UtcModel utcModel) {
+            mUtcModel = utcModel;
+            return this;
+        }
+
+        /** Sets the leap seconds model. */
+        @NonNull
+        public Builder setLeapSecondsModel(@Nullable LeapSecondsModel leapSecondsModel) {
+            mLeapSecondsModel = leapSecondsModel;
+            return this;
+        }
+
+        /** Sets the list of time models. */
+        @NonNull
+        public Builder setTimeModels(
+                @Nullable @SuppressLint("NullableCollection") List<TimeModel> timeModels) {
+            mTimeModels = timeModels;
+            return this;
+        }
+
+        /** Sets the list of Beidou ephemeris. */
+        @NonNull
+        public Builder setSatelliteEphemeris(
+                @Nullable @SuppressLint("NullableCollection")
+                        List<BeidouSatelliteEphemeris> satelliteEphemeris) {
+            mSatelliteEphemeris = satelliteEphemeris;
+            return this;
+        }
+
+        /** Sets the list of real time integrity models. */
+        @NonNull
+        public Builder setRealTimeIntegrityModels(
+                @Nullable @SuppressLint("NullableCollection")
+                        List<RealTimeIntegrityModel> realTimeIntegrityModels) {
+            mRealTimeIntegrityModels = realTimeIntegrityModels;
+            return this;
+        }
+
+        /** Sets the list of Beidou satellite corrections. */
+        @NonNull
+        public Builder setSatelliteCorrections(
+                @Nullable @SuppressLint("NullableCollection")
+                        List<GnssSatelliteCorrections> satelliteCorrections) {
+            mSatelliteCorrections = satelliteCorrections;
+            return this;
+        }
+
+        /** Builds the {@link BeidouAssistance}. */
+        @NonNull
+        public BeidouAssistance build() {
+            return new BeidouAssistance(this);
+        }
+    }
+}
diff --git a/location/java/android/location/BeidouSatelliteEphemeris.java b/location/java/android/location/BeidouSatelliteEphemeris.java
new file mode 100644
index 0000000..6bd91e3
--- /dev/null
+++ b/location/java/android/location/BeidouSatelliteEphemeris.java
@@ -0,0 +1,647 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains ephemeris parameters specific to Beidou satellites.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class BeidouSatelliteEphemeris implements Parcelable {
+    /** The PRN number of the Beidou satellite. */
+    private final int mPrn;
+
+    /** Satellite clock model. */
+    private final BeidouSatelliteClockModel mSatelliteClockModel;
+
+    /** Satellite orbit model. */
+    private final KeplerianOrbitModel mSatelliteOrbitModel;
+
+    /** Satellite health. */
+    private final BeidouSatelliteHealth mSatelliteHealth;
+
+    /** Satellite ephemeris time. */
+    private final BeidouSatelliteEphemerisTime mSatelliteEphemerisTime;
+
+    private BeidouSatelliteEphemeris(Builder builder) {
+        // Allow PRN beyond the range to support potential future extensibility.
+        Preconditions.checkArgument(builder.mPrn >= 1);
+        Preconditions.checkNotNull(builder.mSatelliteClockModel,
+                "SatelliteClockModel cannot be null");
+        Preconditions.checkNotNull(builder.mSatelliteOrbitModel,
+                "SatelliteOrbitModel cannot be null");
+        Preconditions.checkNotNull(builder.mSatelliteHealth,
+                "SatelliteHealth cannot be null");
+        Preconditions.checkNotNull(builder.mSatelliteEphemerisTime,
+                "SatelliteEphemerisTime cannot be null");
+        mPrn = builder.mPrn;
+        mSatelliteClockModel = builder.mSatelliteClockModel;
+        mSatelliteOrbitModel = builder.mSatelliteOrbitModel;
+        mSatelliteHealth = builder.mSatelliteHealth;
+        mSatelliteEphemerisTime = builder.mSatelliteEphemerisTime;
+    }
+
+    /** Returns the PRN of the satellite. */
+    @IntRange(from = 1, to = 63)
+    public int getPrn() {
+        return mPrn;
+    }
+
+    /** Returns the satellite clock model. */
+    @NonNull
+    public BeidouSatelliteClockModel getSatelliteClockModel() {
+        return mSatelliteClockModel;
+    }
+
+    /** Returns the satellite orbit model. */
+    @NonNull
+    public KeplerianOrbitModel getSatelliteOrbitModel() {
+        return mSatelliteOrbitModel;
+    }
+
+    /** Returns the satellite health. */
+    @NonNull
+    public BeidouSatelliteHealth getSatelliteHealth() {
+        return mSatelliteHealth;
+    }
+
+    /** Returns the satellite ephemeris time. */
+    @NonNull
+    public BeidouSatelliteEphemerisTime getSatelliteEphemerisTime() {
+        return mSatelliteEphemerisTime;
+    }
+
+    public static final @NonNull Creator<BeidouSatelliteEphemeris> CREATOR =
+            new Creator<BeidouSatelliteEphemeris>() {
+                @Override
+                @NonNull
+                public BeidouSatelliteEphemeris createFromParcel(Parcel in) {
+                    final BeidouSatelliteEphemeris.Builder beidouSatelliteEphemeris =
+                            new Builder()
+                                    .setPrn(in.readInt())
+                                    .setSatelliteClockModel(
+                                            in.readTypedObject(BeidouSatelliteClockModel.CREATOR))
+                                    .setSatelliteOrbitModel(
+                                            in.readTypedObject(KeplerianOrbitModel.CREATOR))
+                                    .setSatelliteHealth(
+                                            in.readTypedObject(BeidouSatelliteHealth.CREATOR))
+                                    .setSatelliteEphemerisTime(
+                                            in.readTypedObject(
+                                                    BeidouSatelliteEphemerisTime.CREATOR));
+                    return beidouSatelliteEphemeris.build();
+                }
+
+                @Override
+                public BeidouSatelliteEphemeris[] newArray(int size) {
+                    return new BeidouSatelliteEphemeris[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeInt(mPrn);
+        parcel.writeTypedObject(mSatelliteClockModel, flags);
+        parcel.writeTypedObject(mSatelliteOrbitModel, flags);
+        parcel.writeTypedObject(mSatelliteHealth, flags);
+        parcel.writeTypedObject(mSatelliteEphemerisTime, flags);
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("BeidouSatelliteEphemeris[");
+        builder.append("prn = ").append(mPrn);
+        builder.append(", satelliteClockModel = ").append(mSatelliteClockModel);
+        builder.append(", satelliteOrbitModel = ").append(mSatelliteOrbitModel);
+        builder.append(", satelliteHealth = ").append(mSatelliteHealth);
+        builder.append(", satelliteEphemerisTime = ").append(mSatelliteEphemerisTime);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /** Builder for {@link BeidouSatelliteEphemeris} */
+    public static final class Builder {
+        private int mPrn;
+        private BeidouSatelliteClockModel mSatelliteClockModel;
+        private KeplerianOrbitModel mSatelliteOrbitModel;
+        private BeidouSatelliteHealth mSatelliteHealth;
+        private BeidouSatelliteEphemerisTime mSatelliteEphemerisTime;
+
+        /** Sets the PRN of the satellite. */
+        @NonNull
+        public Builder setPrn(int prn) {
+            mPrn = prn;
+            return this;
+        }
+
+        /** Sets the satellite clock model. */
+        @NonNull
+        public Builder setSatelliteClockModel(
+                @NonNull BeidouSatelliteClockModel satelliteClockModel) {
+            mSatelliteClockModel = satelliteClockModel;
+            return this;
+        }
+
+        /** Sets the satellite orbit model. */
+        @NonNull
+        public Builder setSatelliteOrbitModel(@NonNull KeplerianOrbitModel satelliteOrbitModel) {
+            mSatelliteOrbitModel = satelliteOrbitModel;
+            return this;
+        }
+
+        /** Sets the satellite health. */
+        @NonNull
+        public Builder setSatelliteHealth(@NonNull BeidouSatelliteHealth satelliteHealth) {
+            mSatelliteHealth = satelliteHealth;
+            return this;
+        }
+
+        /** Sets the satellite ephemeris time. */
+        @NonNull
+        public Builder setSatelliteEphemerisTime(
+                @NonNull BeidouSatelliteEphemerisTime satelliteEphemerisTime) {
+            mSatelliteEphemerisTime = satelliteEphemerisTime;
+            return this;
+        }
+
+        /** Builds a {@link BeidouSatelliteEphemeris} instance as specified by this builder. */
+        @NonNull
+        public BeidouSatelliteEphemeris build() {
+            return new BeidouSatelliteEphemeris(this);
+        }
+    }
+
+    /**
+     * A class contains the set of parameters needed for Beidou satellite clock correction.
+     *
+     * <p>This is defined in BDS-SIS-ICD-B1I-3.0, section 5.2.4.9, 5.2.4.10.
+     */
+    public static final class BeidouSatelliteClockModel implements Parcelable {
+        /**
+         * Time of the clock in seconds since Beidou epoch.
+         *
+         * <p>Corresponds to the 'Epoch' field within the 'SV/EPOCH/SV CLK' record of Beidou
+         * navigation message in RINEX 3.05 Table A14.
+         */
+        private final long mTimeOfClockSeconds;
+
+        /** SV clock bias in seconds. */
+        private final double mAf0;
+
+        /** SV clock drift in seconds per second. */
+        private final double mAf1;
+
+        /** SV clock drift in seconds per second squared. */
+        private final double mAf2;
+
+        /** Group delay differential 1 B1/B3 in seconds. */
+        private final double mTgd1;
+
+        /** Group delay differential 2 B2/B3 in seconds. */
+        private final double mTgd2;
+
+        /**
+         * Age of Data Clock.
+         * <p>This is defined in BDS-SIS-ICD-B1I-3.0 Section 5.2.4.8 Table 5-6.
+         */
+        private final int mAodc;
+
+        private BeidouSatelliteClockModel(Builder builder) {
+            Preconditions.checkArgument(builder.mTimeOfClockSeconds >= 0);
+            Preconditions.checkArgumentInRange(builder.mAf0, -9.77e-3f, 9.77e-3f, "Af0");
+            Preconditions.checkArgumentInRange(builder.mAf1, -1.87e-9f, 1.87e-9f, "Af1");
+            Preconditions.checkArgumentInRange(builder.mAf2, -1.39e-17f, 1.39e-17f, "Af2");
+            Preconditions.checkArgumentInRange(builder.mTgd1, -5.12e-8f, 5.12e-8f, "Tgd1");
+            Preconditions.checkArgumentInRange(builder.mTgd2, -5.12e-8f, 5.12e-8f, "Tgd2");
+            Preconditions.checkArgumentInRange(builder.mAodc, 0, 31, "Aodc");
+            mTimeOfClockSeconds = builder.mTimeOfClockSeconds;
+            mAf0 = builder.mAf0;
+            mAf1 = builder.mAf1;
+            mAf2 = builder.mAf2;
+            mTgd1 = builder.mTgd1;
+            mTgd2 = builder.mTgd2;
+            mAodc = builder.mAodc;
+        }
+
+        /** Returns the time of the clock in seconds since Beidou epoch. */
+        @IntRange(from = 0)
+        public long getTimeOfClockSeconds() {
+            return mTimeOfClockSeconds;
+        }
+
+        /** Returns the SV clock bias in seconds. */
+        @FloatRange(from = -9.77e-3f, to = 9.77e-3f)
+        public double getAf0() {
+            return mAf0;
+        }
+
+        /** Returns the SV clock drift in seconds per second. */
+        @FloatRange(from = -1.87e-9f, to = 1.87e-9f)
+        public double getAf1() {
+            return mAf1;
+        }
+
+        /** Returns the SV clock drift in seconds per second squared. */
+        @FloatRange(from = -1.39e-17f, to = 1.39e-17f)
+        public double getAf2() {
+            return mAf2;
+        }
+
+        /** Returns the group delay differential 1 B1/B3 in seconds. */
+        @FloatRange(from = -5.12e-8f, to = 5.12e-8f)
+        public double getTgd1() {
+            return mTgd1;
+        }
+
+        /** Returns the group delay differential 2 B2/B3 in seconds. */
+        @FloatRange(from = -5.12e-8f, to = 5.12e-8f)
+        public double getTgd2() {
+            return mTgd2;
+        }
+
+        /** Returns the age of data clock. */
+        @IntRange(from = 0, to = 31)
+        public int getAodc() {
+            return mAodc;
+        }
+
+        public static final @NonNull Creator<BeidouSatelliteClockModel> CREATOR =
+                new Creator<BeidouSatelliteClockModel>() {
+                    @Override
+                    @NonNull
+                    public BeidouSatelliteClockModel createFromParcel(Parcel in) {
+                        final BeidouSatelliteClockModel.Builder beidouSatelliteClockModel =
+                                new Builder()
+                                        .setTimeOfClockSeconds(in.readLong())
+                                        .setAf0(in.readDouble())
+                                        .setAf1(in.readDouble())
+                                        .setAf2(in.readDouble())
+                                        .setTgd1(in.readDouble())
+                                        .setTgd2(in.readDouble())
+                                        .setAodc(in.readInt());
+                        return beidouSatelliteClockModel.build();
+                    }
+
+                    @Override
+                    public BeidouSatelliteClockModel[] newArray(int size) {
+                        return new BeidouSatelliteClockModel[size];
+                    }
+                };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel parcel, int flags) {
+            parcel.writeLong(mTimeOfClockSeconds);
+            parcel.writeDouble(mAf0);
+            parcel.writeDouble(mAf1);
+            parcel.writeDouble(mAf2);
+            parcel.writeDouble(mTgd1);
+            parcel.writeDouble(mTgd2);
+            parcel.writeInt(mAodc);
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            StringBuilder builder = new StringBuilder("BeidouSatelliteClockModel[");
+            builder.append("timeOfClockSeonds = ").append(mTimeOfClockSeconds);
+            builder.append(", af0 = ").append(mAf0);
+            builder.append(", af1 = ").append(mAf1);
+            builder.append(", af2 = ").append(mAf2);
+            builder.append(", tgd1 = ").append(mTgd1);
+            builder.append(", tgd2 = ").append(mTgd2);
+            builder.append(", aodc = ").append(mAodc);
+            return builder.toString();
+        }
+
+        /** Builder for {@link BeidouSatelliteClockModel} */
+        public static final class Builder {
+            private long mTimeOfClockSeconds;
+            private double mAf0;
+            private double mAf1;
+            private double mAf2;
+            private double mTgd1;
+            private double mTgd2;
+            private int mAodc;
+
+            /** Sets the time of the clock in seconds since Beidou epoch. */
+            @NonNull
+            public Builder setTimeOfClockSeconds(@IntRange(from = 0) long timeOfClockSeconds) {
+                mTimeOfClockSeconds = timeOfClockSeconds;
+                return this;
+            }
+
+            /** Sets the SV clock bias in seconds. */
+            @NonNull
+            public Builder setAf0(@FloatRange(from = -9.77e-3f, to = 9.77e-3f)double af0) {
+                mAf0 = af0;
+                return this;
+            }
+
+            /** Sets the SV clock drift in seconds per second. */
+            @NonNull
+            public Builder setAf1(@FloatRange(from = -1.87e-9f, to = 1.87e-9f) double af1) {
+                mAf1 = af1;
+                return this;
+            }
+
+            /** Sets the SV clock drift in seconds per second squared. */
+            @NonNull
+            public Builder setAf2(@FloatRange(from = -1.39e-17f, to = 1.39e-17f) double af2) {
+                mAf2 = af2;
+                return this;
+            }
+
+            /** Sets the group delay differential 1 B1/B3 in seconds. */
+            @NonNull
+            public Builder setTgd1(@FloatRange(from = -5.12e-8f, to = 5.12e-8f) double tgd1) {
+                mTgd1 = tgd1;
+                return this;
+            }
+
+            /** Sets the group delay differential 2 B2/B3 in seconds. */
+            @NonNull
+            public Builder setTgd2(@FloatRange(from = -5.12e-8f, to = 5.12e-8f) double tgd2) {
+                mTgd2 = tgd2;
+                return this;
+            }
+
+            /** Sets the age of data clock. */
+            @NonNull
+            public Builder setAodc(@IntRange(from = 0, to = 31) int aodc) {
+                mAodc = aodc;
+                return this;
+            }
+
+            /** Builds a {@link BeidouSatelliteClockModel} instance as specified by this builder. */
+            @NonNull
+            public BeidouSatelliteClockModel build() {
+                return new BeidouSatelliteClockModel(this);
+            }
+        }
+    }
+
+    /** A class contains Beidou satellite health. */
+    public static final class BeidouSatelliteHealth implements Parcelable {
+        /**
+         * The autonomous satellite health flag (SatH1) occupies 1 bit.
+         *
+         * <p>“0” means broadcasting satellite is good and “1” means not.
+         *
+         * <p>This is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.6.
+         */
+        private final int mSatH1;
+
+        /**
+         * SV accuracy in meters.
+         *
+         * <p>This is defined in the "BROADCAST ORBIT - 6" record of RINEX 3.05
+         * Table A14, pp.78.
+         */
+        private final double mSvAccur;
+
+        private BeidouSatelliteHealth(Builder builder) {
+            // Allow SatH1 beyond the range to support potential future extensibility.
+            Preconditions.checkArgument(builder.mSatH1 >= 0);
+            Preconditions.checkArgumentInRange(builder.mSvAccur, 0.0f, 8192.0f, "SvAccur");
+            mSatH1 = builder.mSatH1;
+            mSvAccur = builder.mSvAccur;
+        }
+
+        /** Returns the autonomous satellite health flag (SatH1) */
+        @IntRange(from = 0, to = 1)
+        public int getSatH1() {
+            return mSatH1;
+        }
+
+        /** Returns the SV accuracy in meters. */
+        @FloatRange(from = 0.0f, to = 8192.0f)
+        public double getSvAccur() {
+            return mSvAccur;
+        }
+
+        public static final @NonNull Creator<BeidouSatelliteHealth> CREATOR =
+                new Creator<BeidouSatelliteHealth>() {
+                    @Override
+                    @NonNull
+                    public BeidouSatelliteHealth createFromParcel(Parcel in) {
+                        final BeidouSatelliteHealth.Builder beidouSatelliteHealth =
+                                new Builder().setSatH1(in.readInt()).setSvAccur(in.readDouble());
+                        return beidouSatelliteHealth.build();
+                    }
+
+                    @Override
+                    public BeidouSatelliteHealth[] newArray(int size) {
+                        return new BeidouSatelliteHealth[size];
+                    }
+                };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel parcel, int flags) {
+            parcel.writeInt(mSatH1);
+            parcel.writeDouble(mSvAccur);
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            StringBuilder builder = new StringBuilder("BeidouSatelliteHealth[");
+            builder.append("satH1 = ").append(mSatH1);
+            builder.append(", svAccur = ").append(mSvAccur);
+            builder.append("]");
+            return builder.toString();
+        }
+
+        /** Builder for {@link BeidouSatelliteHealth} */
+        public static final class Builder {
+            private int mSatH1;
+            private double mSvAccur;
+
+            /** Sets the autonomous satellite health flag (SatH1) */
+            @NonNull
+            public Builder setSatH1(int satH1) {
+                mSatH1 = satH1;
+                return this;
+            }
+
+            /** Sets the SV accuracy in meters. */
+            @NonNull
+            public Builder setSvAccur(double svAccur) {
+                mSvAccur = svAccur;
+                return this;
+            }
+
+            /** Builds a {@link BeidouSatelliteHealth} instance as specified by this builder. */
+            @NonNull
+            public BeidouSatelliteHealth build() {
+                return new BeidouSatelliteHealth(this);
+            }
+        }
+    }
+
+    /** A class contains Beidou satellite ephemeris time. */
+    public static final class BeidouSatelliteEphemerisTime implements Parcelable {
+        /**
+         * AODE Age of Data, Ephemeris.
+         *
+         * <p>This is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.11 Table 5-8.
+         */
+        private final int mIode;
+
+        /** Beidou week number without rollover */
+        private final int mBeidouWeekNumber;
+
+        /**
+         * Time of ephemeris in seconds.
+         *
+         * <p>This is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.12.
+         */
+        private final int mToeSeconds;
+
+        private BeidouSatelliteEphemerisTime(Builder builder) {
+            Preconditions.checkArgumentInRange(builder.mIode, 0, 31, "Iode");
+            Preconditions.checkArgument(builder.mBeidouWeekNumber >= 0);
+            Preconditions.checkArgumentInRange(builder.mToeSeconds, 0, 604792, "ToeSeconds");
+            mIode = builder.mIode;
+            mBeidouWeekNumber = builder.mBeidouWeekNumber;
+            mToeSeconds = builder.mToeSeconds;
+        }
+
+        /** Returns the AODE Age of Data, Ephemeris. */
+        @IntRange(from = 0, to = 31)
+        public int getIode() {
+            return mIode;
+        }
+
+        /** Returns the Beidou week number without rollover . */
+        @IntRange(from = 0)
+        public int getBeidouWeekNumber() {
+            return mBeidouWeekNumber;
+        }
+
+        /** Returns the time of ephemeris in seconds. */
+        @IntRange(from = 0, to = 604792)
+        public int getToeSeconds() {
+            return mToeSeconds;
+        }
+
+        public static final @NonNull Creator<BeidouSatelliteEphemerisTime> CREATOR =
+                new Creator<BeidouSatelliteEphemerisTime>() {
+                    @Override
+                    @NonNull
+                    public BeidouSatelliteEphemerisTime createFromParcel(Parcel in) {
+                        final BeidouSatelliteEphemerisTime.Builder beidouSatelliteEphemerisTime =
+                                new Builder()
+                                        .setIode(in.readInt())
+                                        .setBeidouWeekNumber(in.readInt())
+                                        .setToeSeconds(in.readInt());
+                        return beidouSatelliteEphemerisTime.build();
+                    }
+
+                    @Override
+                    public BeidouSatelliteEphemerisTime[] newArray(int size) {
+                        return new BeidouSatelliteEphemerisTime[size];
+                    }
+                };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel parcel, int flags) {
+            parcel.writeInt(mIode);
+            parcel.writeInt(mBeidouWeekNumber);
+            parcel.writeInt(mToeSeconds);
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder builder = new StringBuilder("BeidouSatelliteEphemerisTime[");
+            builder.append("iode = ").append(mIode);
+            builder.append(", beidouWeekNumber = ").append(mBeidouWeekNumber);
+            builder.append(", toeSeconds = ").append(mToeSeconds);
+            builder.append("]");
+            return builder.toString();
+        }
+
+        /** Builder for {@link BeidouSatelliteEphemerisTime} */
+        public static final class Builder {
+            private int mIode;
+            private int mBeidouWeekNumber;
+            private int mToeSeconds;
+
+            /** Sets the AODE Age of Data, Ephemeris. */
+            @NonNull
+            public Builder setIode(int iode) {
+                mIode = iode;
+                return this;
+            }
+
+            /** Sets the Beidou week number without rollover */
+            @NonNull
+            public Builder setBeidouWeekNumber(
+                    @IntRange(from = 0) int beidouWeekNumber) {
+                mBeidouWeekNumber = beidouWeekNumber;
+                return this;
+            }
+
+            /** Sets the time of ephemeris in seconds. */
+            @NonNull
+            public Builder setToeSeconds(@IntRange(from = 0, to = 604792) int toeSeconds) {
+                mToeSeconds = toeSeconds;
+                return this;
+            }
+
+            /**
+             * Builds a {@link BeidouSatelliteEphemerisTime} instance as specified by this builder.
+             */
+            @NonNull
+            public BeidouSatelliteEphemerisTime build() {
+                return new BeidouSatelliteEphemerisTime(this);
+            }
+        }
+    }
+}
diff --git a/location/java/android/location/GalileoAssistance.java b/location/java/android/location/GalileoAssistance.java
new file mode 100644
index 0000000..07c5bab
--- /dev/null
+++ b/location/java/android/location/GalileoAssistance.java
@@ -0,0 +1,283 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.location.GnssAssistance.GnssSatelliteCorrections;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class contains Galileo assistance.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GalileoAssistance implements Parcelable {
+
+    /** The Galileo almanac. */
+    @Nullable private final GnssAlmanac mAlmanac;
+
+    /** The Klobuchar ionospheric model. */
+    @Nullable private final KlobucharIonosphericModel mIonosphericModel;
+
+    /** The UTC model. */
+    @Nullable private final UtcModel mUtcModel;
+
+    /** The leap seconds model. */
+    @Nullable private final LeapSecondsModel mLeapSecondsModel;
+
+    /** The list of time models. */
+    @NonNull private final List<TimeModel> mTimeModels;
+
+    /** The list of Galileo ephemeris. */
+    @NonNull private final List<GalileoSatelliteEphemeris> mSatelliteEphemeris;
+
+    /** The list of real time integrity models. */
+    @NonNull private final List<RealTimeIntegrityModel> mRealTimeIntegrityModels;
+
+    /** The list of Galileo satellite corrections. */
+    @NonNull private final List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+    private GalileoAssistance(Builder builder) {
+        mAlmanac = builder.mAlmanac;
+        mIonosphericModel = builder.mIonosphericModel;
+        mUtcModel = builder.mUtcModel;
+        mLeapSecondsModel = builder.mLeapSecondsModel;
+        if (builder.mTimeModels != null) {
+            mTimeModels = Collections.unmodifiableList(new ArrayList<>(builder.mTimeModels));
+        } else {
+            mTimeModels = new ArrayList<>();
+        }
+        if (builder.mSatelliteEphemeris != null) {
+            mSatelliteEphemeris =
+                    Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteEphemeris));
+        } else {
+            mSatelliteEphemeris = new ArrayList<>();
+        }
+        if (builder.mRealTimeIntegrityModels != null) {
+            mRealTimeIntegrityModels =
+                    Collections.unmodifiableList(new ArrayList<>(builder.mRealTimeIntegrityModels));
+        } else {
+            mRealTimeIntegrityModels = new ArrayList<>();
+        }
+        if (builder.mSatelliteCorrections != null) {
+            mSatelliteCorrections =
+                    Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteCorrections));
+        } else {
+            mSatelliteCorrections = new ArrayList<>();
+        }
+    }
+
+    /** Returns the Galileo almanac. */
+    @Nullable
+    public GnssAlmanac getAlmanac() {
+        return mAlmanac;
+    }
+
+    /** Returns the Klobuchar ionospheric model. */
+    @Nullable
+    public KlobucharIonosphericModel getIonosphericModel() {
+        return mIonosphericModel;
+    }
+
+    /** Returns the UTC model. */
+    @Nullable
+    public UtcModel getUtcModel() {
+        return mUtcModel;
+    }
+
+    /** Returns the leap seconds model. */
+    @Nullable
+    public LeapSecondsModel getLeapSecondsModel() {
+        return mLeapSecondsModel;
+    }
+
+    /** Returns the list of time models. */
+    @NonNull
+    public List<TimeModel> getTimeModels() {
+        return mTimeModels;
+    }
+
+    /** Returns the list of Galileo ephemeris. */
+    @NonNull
+    public List<GalileoSatelliteEphemeris> getSatelliteEphemeris() {
+        return mSatelliteEphemeris;
+    }
+
+    /** Returns the list of real time integrity models. */
+    @NonNull
+    public List<RealTimeIntegrityModel> getRealTimeIntegrityModels() {
+        return mRealTimeIntegrityModels;
+    }
+
+    /** Returns the list of Galileo satellite corrections. */
+    @NonNull
+    public List<GnssSatelliteCorrections> getSatelliteCorrections() {
+        return mSatelliteCorrections;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeTypedObject(mAlmanac, flags);
+        dest.writeTypedObject(mIonosphericModel, flags);
+        dest.writeTypedObject(mUtcModel, flags);
+        dest.writeTypedObject(mLeapSecondsModel, flags);
+        dest.writeTypedList(mTimeModels);
+        dest.writeTypedList(mSatelliteEphemeris);
+        dest.writeTypedList(mRealTimeIntegrityModels);
+        dest.writeTypedList(mSatelliteCorrections);
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("GalileoAssistance[");
+        builder.append("almanac = ").append(mAlmanac);
+        builder.append(", ionosphericModel = ").append(mIonosphericModel);
+        builder.append(", utcModel = ").append(mUtcModel);
+        builder.append(", leapSecondsModel = ").append(mLeapSecondsModel);
+        builder.append(", timeModels = ").append(mTimeModels);
+        builder.append(", satelliteEphemeris = ").append(mSatelliteEphemeris);
+        builder.append(", realTimeIntegrityModels = ").append(mRealTimeIntegrityModels);
+        builder.append(", satelliteCorrections = ").append(mSatelliteCorrections);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    public static final @android.annotation.NonNull Creator<GalileoAssistance> CREATOR =
+            new Creator<GalileoAssistance>() {
+                @Override
+                public GalileoAssistance createFromParcel(Parcel in) {
+                    return new GalileoAssistance.Builder()
+                            .setAlmanac(in.readTypedObject(GnssAlmanac.CREATOR))
+                            .setIonosphericModel(
+                                    in.readTypedObject(KlobucharIonosphericModel.CREATOR))
+                            .setUtcModel(in.readTypedObject(UtcModel.CREATOR))
+                            .setLeapSecondsModel(in.readTypedObject(LeapSecondsModel.CREATOR))
+                            .setTimeModels(in.createTypedArrayList(TimeModel.CREATOR))
+                            .setSatelliteEphemeris(
+                                    in.createTypedArrayList(GalileoSatelliteEphemeris.CREATOR))
+                            .setRealTimeIntegrityModels(
+                                    in.createTypedArrayList(RealTimeIntegrityModel.CREATOR))
+                            .setSatelliteCorrections(
+                                    in.createTypedArrayList(GnssSatelliteCorrections.CREATOR))
+                            .build();
+                }
+
+                @Override
+                public GalileoAssistance[] newArray(int size) {
+                    return new GalileoAssistance[size];
+                }
+            };
+
+    /** Builder for {@link GalileoAssistance}. */
+    public static final class Builder {
+        private GnssAlmanac mAlmanac;
+        private KlobucharIonosphericModel mIonosphericModel;
+        private UtcModel mUtcModel;
+        private LeapSecondsModel mLeapSecondsModel;
+        private List<TimeModel> mTimeModels;
+        private List<GalileoSatelliteEphemeris> mSatelliteEphemeris;
+        private List<RealTimeIntegrityModel> mRealTimeIntegrityModels;
+        private List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+        /** Sets the Galileo almanac. */
+        @NonNull
+        public Builder setAlmanac(@Nullable GnssAlmanac almanac) {
+            mAlmanac = almanac;
+            return this;
+        }
+
+        /** Sets the Klobuchar ionospheric model. */
+        @NonNull
+        public Builder setIonosphericModel(@Nullable KlobucharIonosphericModel ionosphericModel) {
+            mIonosphericModel = ionosphericModel;
+            return this;
+        }
+
+        /** Sets the UTC model. */
+        @NonNull
+        public Builder setUtcModel(@Nullable UtcModel utcModel) {
+            mUtcModel = utcModel;
+            return this;
+        }
+
+        /** Sets the leap seconds model. */
+        @NonNull
+        public Builder setLeapSecondsModel(@Nullable LeapSecondsModel leapSecondsModel) {
+            mLeapSecondsModel = leapSecondsModel;
+            return this;
+        }
+
+        /** Sets the list of time models. */
+        @NonNull
+        public Builder setTimeModels(
+                @Nullable @SuppressLint("NullableCollection") List<TimeModel> timeModels) {
+            mTimeModels = timeModels;
+            return this;
+        }
+
+        /** Sets the list of Galileo ephemeris. */
+        @NonNull
+        public Builder setSatelliteEphemeris(
+                @Nullable @SuppressLint("NullableCollection")
+                        List<GalileoSatelliteEphemeris> satelliteEphemeris) {
+            mSatelliteEphemeris = satelliteEphemeris;
+            return this;
+        }
+
+        /** Sets the list of real time integrity models. */
+        @NonNull
+        public Builder setRealTimeIntegrityModels(
+                @Nullable @SuppressLint("NullableCollection")
+                        List<RealTimeIntegrityModel> realTimeIntegrityModels) {
+            mRealTimeIntegrityModels = realTimeIntegrityModels;
+            return this;
+        }
+
+        /** Sets the list of Galileo satellite corrections. */
+        @NonNull
+        public Builder setSatelliteCorrections(
+                @Nullable @SuppressLint("NullableCollection")
+                        List<GnssSatelliteCorrections> satelliteCorrections) {
+            mSatelliteCorrections = satelliteCorrections;
+            return this;
+        }
+
+        /** Builds the {@link GalileoAssistance}. */
+        @NonNull
+        public GalileoAssistance build() {
+            return new GalileoAssistance(this);
+        }
+    }
+}
diff --git a/location/java/android/location/GalileoIonosphericModel.java b/location/java/android/location/GalileoIonosphericModel.java
new file mode 100644
index 0000000..6638be9
--- /dev/null
+++ b/location/java/android/location/GalileoIonosphericModel.java
@@ -0,0 +1,148 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Contains Galileo ionospheric model.
+ *
+ * <p>This is defined in Galileo-OS-SIS-ICD-v2.1, section 5.1.6.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GalileoIonosphericModel implements Parcelable {
+    /** Effective ionisation level 1st order parameter in sfu. */
+    private final double mAi0;
+
+    /** Effective ionisation level 2nd order parameter in sfu per degree. */
+    private final double mAi1;
+
+    /** Effective ionisation level 3nd order parameter in sfu per degree squared. */
+    private final double mAi2;
+
+    private GalileoIonosphericModel(Builder builder) {
+        Preconditions.checkArgumentInRange(builder.mAi0, 0.0f, 512.0f, "Ai0");
+        Preconditions.checkArgumentInRange(builder.mAi1, -4.0f, 4.0f, "Ai1");
+        Preconditions.checkArgumentInRange(builder.mAi2, -0.5f, 0.5f, "Ai2");
+        mAi0 = builder.mAi0;
+        mAi1 = builder.mAi1;
+        mAi2 = builder.mAi2;
+    }
+
+    /** Returns the effective ionisation level 1st order parameter in sfu. */
+    @FloatRange(from = 0.0f, to = 512.0f)
+    public double getAi0() {
+        return mAi0;
+    }
+
+    /** Returns the effective ionisation level 2nd order parameter in sfu per degree. */
+    @FloatRange(from = -4.0f, to = 4.0f)
+    public double getAi1() {
+        return mAi1;
+    }
+
+    /** Returns the effective ionisation level 3nd order parameter in sfu per degree squared. */
+    @FloatRange(from = -0.5f, to = 0.5f)
+    public double getAi2() {
+        return mAi2;
+    }
+
+    public static final @NonNull Parcelable.Creator<GalileoIonosphericModel> CREATOR =
+            new Parcelable.Creator<GalileoIonosphericModel>() {
+                @Override
+                public GalileoIonosphericModel createFromParcel(@NonNull Parcel source) {
+                    return new GalileoIonosphericModel.Builder()
+                            .setAi0(source.readDouble())
+                            .setAi1(source.readDouble())
+                            .setAi2(source.readDouble())
+                            .build();
+                }
+
+                @Override
+                public GalileoIonosphericModel[] newArray(int size) {
+                    return new GalileoIonosphericModel[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeDouble(mAi0);
+        dest.writeDouble(mAi1);
+        dest.writeDouble(mAi2);
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("GalileoIonosphericModel[");
+        builder.append("ai0 = ").append(mAi0);
+        builder.append(", ai1 = ").append(mAi1);
+        builder.append(", ai2 = ").append(mAi2);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /** Builder for {@link GalileoIonosphericModel}. */
+    public static final class Builder {
+        private double mAi0;
+        private double mAi1;
+        private double mAi2;
+
+        /** Sets the effective ionisation level 1st order parameter in sfu. */
+        @NonNull
+        public Builder setAi0(@FloatRange(from = 0.0f, to = 512.0f) double ai0) {
+            mAi0 = ai0;
+            return this;
+        }
+
+        /** Sets the effective ionisation level 2nd order parameter in sfu per degree. */
+        @NonNull
+        public Builder setAi1(@FloatRange(from = -4.0f, to = 4.0f) double ai1) {
+            mAi1 = ai1;
+            return this;
+        }
+
+        /** Sets the effective ionisation level 3nd order parameter in sfu per degree squared. */
+        @NonNull
+        public Builder setAi2(@FloatRange(from = -0.5f, to = 0.5f) double ai2) {
+            mAi2 = ai2;
+            return this;
+        }
+
+        /** Builds a {@link GalileoIonosphericModel}. */
+        @NonNull
+        public GalileoIonosphericModel build() {
+            return new GalileoIonosphericModel(this);
+        }
+    }
+}
diff --git a/location/java/android/location/GalileoSatelliteEphemeris.java b/location/java/android/location/GalileoSatelliteEphemeris.java
new file mode 100644
index 0000000..7dd3711
--- /dev/null
+++ b/location/java/android/location/GalileoSatelliteEphemeris.java
@@ -0,0 +1,660 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Contains ephemeris parameters specific to Galileo satellites.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GalileoSatelliteEphemeris implements Parcelable {
+
+    /** Satellite code number. */
+    private int mSatelliteCodeNumber;
+
+    /** Array of satellite clock model. */
+    @NonNull private final List<GalileoSatelliteClockModel> mSatelliteClockModels;
+
+    /** Satellite orbit model. */
+    @NonNull private final KeplerianOrbitModel mSatelliteOrbitModel;
+
+    /** Satellite health. */
+    @NonNull private final GalileoSvHealth mSatelliteHealth;
+
+    /** Satellite ephemeris time. */
+    @NonNull private final SatelliteEphemerisTime mSatelliteEphemerisTime;
+
+    private GalileoSatelliteEphemeris(Builder builder) {
+        // Allow satelliteCodeNumber beyond the range to support potential future extensibility.
+        Preconditions.checkArgument(builder.mSatelliteCodeNumber >= 1);
+        Preconditions.checkNotNull(
+                builder.mSatelliteClockModels, "SatelliteClockModels cannot be null");
+        Preconditions.checkNotNull(
+                builder.mSatelliteOrbitModel, "SatelliteOrbitModel cannot be null");
+        Preconditions.checkNotNull(builder.mSatelliteHealth, "SatelliteHealth cannot be null");
+        Preconditions.checkNotNull(
+                builder.mSatelliteEphemerisTime, "SatelliteEphemerisTime cannot be null");
+        mSatelliteCodeNumber = builder.mSatelliteCodeNumber;
+        final List<GalileoSatelliteClockModel> satelliteClockModels = builder.mSatelliteClockModels;
+        mSatelliteClockModels = Collections.unmodifiableList(new ArrayList<>(satelliteClockModels));
+        mSatelliteOrbitModel = builder.mSatelliteOrbitModel;
+        mSatelliteHealth = builder.mSatelliteHealth;
+        mSatelliteEphemerisTime = builder.mSatelliteEphemerisTime;
+    }
+
+    /** Returns the satellite code number. */
+    @IntRange(from = 1, to = 36)
+    public int getSatelliteCodeNumber() {
+        return mSatelliteCodeNumber;
+    }
+
+    /** Returns the list of satellite clock models. */
+    @NonNull
+    public List<GalileoSatelliteClockModel> getSatelliteClockModels() {
+        return mSatelliteClockModels;
+    }
+
+    /** Returns the satellite orbit model. */
+    @NonNull
+    public KeplerianOrbitModel getSatelliteOrbitModel() {
+        return mSatelliteOrbitModel;
+    }
+
+    /** Returns the satellite health. */
+    @NonNull
+    public GalileoSvHealth getSatelliteHealth() {
+        return mSatelliteHealth;
+    }
+
+    /** Returns the satellite ephemeris time. */
+    @NonNull
+    public SatelliteEphemerisTime getSatelliteEphemerisTime() {
+        return mSatelliteEphemerisTime;
+    }
+
+    public static final @NonNull Creator<GalileoSatelliteEphemeris> CREATOR =
+            new Creator<GalileoSatelliteEphemeris>() {
+                @Override
+                @NonNull
+                public GalileoSatelliteEphemeris createFromParcel(Parcel in) {
+                    final GalileoSatelliteEphemeris.Builder galileoSatelliteEphemeris =
+                            new Builder();
+                    galileoSatelliteEphemeris.setSatelliteCodeNumber(in.readInt());
+                    List<GalileoSatelliteClockModel> satelliteClockModels = new ArrayList<>();
+                    in.readTypedList(satelliteClockModels, GalileoSatelliteClockModel.CREATOR);
+                    galileoSatelliteEphemeris.setSatelliteClockModels(satelliteClockModels);
+                    galileoSatelliteEphemeris.setSatelliteOrbitModel(
+                            in.readTypedObject(KeplerianOrbitModel.CREATOR));
+                    galileoSatelliteEphemeris.setSatelliteHealth(
+                            in.readTypedObject(GalileoSvHealth.CREATOR));
+                    galileoSatelliteEphemeris.setSatelliteEphemerisTime(
+                            in.readTypedObject(SatelliteEphemerisTime.CREATOR));
+                    return galileoSatelliteEphemeris.build();
+                }
+
+                @Override
+                public GalileoSatelliteEphemeris[] newArray(int size) {
+                    return new GalileoSatelliteEphemeris[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeInt(mSatelliteCodeNumber);
+        parcel.writeTypedList(mSatelliteClockModels, flags);
+        parcel.writeTypedObject(mSatelliteOrbitModel, flags);
+        parcel.writeTypedObject(mSatelliteHealth, flags);
+        parcel.writeTypedObject(mSatelliteEphemerisTime, flags);
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("GalileoSatelliteEphemeris[");
+        builder.append("satelliteCodeNumber = ").append(mSatelliteCodeNumber);
+        builder.append(", satelliteClockModels = ").append(mSatelliteClockModels);
+        builder.append(", satelliteOrbitModel = ").append(mSatelliteOrbitModel);
+        builder.append(", satelliteHealth = ").append(mSatelliteHealth);
+        builder.append(", satelliteEphemerisTime = ").append(mSatelliteEphemerisTime);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /** Builder for {@link GalileoSatelliteEphemeris}. */
+    public static final class Builder {
+        private int mSatelliteCodeNumber;
+        private List<GalileoSatelliteClockModel> mSatelliteClockModels;
+        private KeplerianOrbitModel mSatelliteOrbitModel;
+        private GalileoSvHealth mSatelliteHealth;
+        private SatelliteEphemerisTime mSatelliteEphemerisTime;
+
+        /** Sets the satellite code number. */
+        @NonNull
+        public Builder setSatelliteCodeNumber(
+                @IntRange(from = 1, to = 36) int satelliteCodeNumber) {
+            mSatelliteCodeNumber = satelliteCodeNumber;
+            return this;
+        }
+
+        /** Sets the array of satellite clock model. */
+        @NonNull
+        public Builder setSatelliteClockModels(
+                @NonNull List<GalileoSatelliteClockModel> satelliteClockModels) {
+            mSatelliteClockModels = satelliteClockModels;
+            return this;
+        }
+
+        /** Sets the satellite orbit model. */
+        @NonNull
+        public Builder setSatelliteOrbitModel(@NonNull KeplerianOrbitModel satelliteOrbitModel) {
+            mSatelliteOrbitModel = satelliteOrbitModel;
+            return this;
+        }
+
+        /** Sets the satellite health. */
+        @NonNull
+        public Builder setSatelliteHealth(@NonNull GalileoSvHealth satelliteHealth) {
+            mSatelliteHealth = satelliteHealth;
+            return this;
+        }
+
+        /** Sets the satellite ephemeris time. */
+        @NonNull
+        public Builder setSatelliteEphemerisTime(
+                @NonNull SatelliteEphemerisTime satelliteEphemerisTime) {
+            mSatelliteEphemerisTime = satelliteEphemerisTime;
+            return this;
+        }
+
+        /** Builds a {@link GalileoSatelliteEphemeris} instance as specified by this builder. */
+        @NonNull
+        public GalileoSatelliteEphemeris build() {
+            return new GalileoSatelliteEphemeris(this);
+        }
+    }
+
+    /**
+     * A class contains the set of parameters needed for Galileo satellite health.
+     *
+     * <p>This is defined in Galileo-OS-SIS-ICD 5.1.9.3.
+     */
+    public static final class GalileoSvHealth implements Parcelable {
+        /** E1-B data validity status. */
+        private int mDataValidityStatusE1b;
+
+        /** E1-B/C signal health status. */
+        private int mSignalHealthStatusE1b;
+
+        /** E5a data validity status. */
+        private int mDataValidityStatusE5a;
+
+        /** E5a signal health status. */
+        private int mSignalHealthStatusE5a;
+
+        /** E5b data validity status. */
+        private int mDataValidityStatusE5b;
+
+        /** E5b signal health status. */
+        private int mSignalHealthStatusE5b;
+
+        private GalileoSvHealth(Builder builder) {
+            Preconditions.checkArgumentInRange(
+                    builder.mDataValidityStatusE1b, 0, 1, "DataValidityStatusE1b");
+            Preconditions.checkArgumentInRange(
+                    builder.mSignalHealthStatusE1b, 0, 3, "SignalHealthStatusE1b");
+            Preconditions.checkArgumentInRange(
+                    builder.mDataValidityStatusE5a, 0, 1, "DataValidityStatusE5a");
+            Preconditions.checkArgumentInRange(
+                    builder.mSignalHealthStatusE5a, 0, 3, "SignalHealthStatusE5a");
+            Preconditions.checkArgumentInRange(
+                    builder.mDataValidityStatusE5b, 0, 1, "DataValidityStatusE5b");
+            Preconditions.checkArgumentInRange(
+                    builder.mSignalHealthStatusE5b, 0, 3, "SignalHealthStatusE5b");
+            mDataValidityStatusE1b = builder.mDataValidityStatusE1b;
+            mSignalHealthStatusE1b = builder.mSignalHealthStatusE1b;
+            mDataValidityStatusE5a = builder.mDataValidityStatusE5a;
+            mSignalHealthStatusE5a = builder.mSignalHealthStatusE5a;
+            mDataValidityStatusE5b = builder.mDataValidityStatusE5b;
+            mSignalHealthStatusE5b = builder.mSignalHealthStatusE5b;
+        }
+
+        /** Returns the E1-B data validity status. */
+        @IntRange(from = 0, to = 1)
+        public int getDataValidityStatusE1b() {
+            return mDataValidityStatusE1b;
+        }
+
+        /** Returns the E1-B/C signal health status. */
+        @IntRange(from = 0, to = 3)
+        public int getSignalHealthStatusE1b() {
+            return mSignalHealthStatusE1b;
+        }
+
+        /** Returns the E5a data validity status. */
+        @IntRange(from = 0, to = 1)
+        public int getDataValidityStatusE5a() {
+            return mDataValidityStatusE5a;
+        }
+
+        /** Returns the E5a signal health status. */
+        @IntRange(from = 0, to = 3)
+        public int getSignalHealthStatusE5a() {
+            return mSignalHealthStatusE5a;
+        }
+
+        /** Returns the E5b data validity status. */
+        @IntRange(from = 0, to = 1)
+        public int getDataValidityStatusE5b() {
+            return mDataValidityStatusE5b;
+        }
+
+        /** Returns the E5b signal health status. */
+        @IntRange(from = 0, to = 3)
+        public int getSignalHealthStatusE5b() {
+            return mSignalHealthStatusE5b;
+        }
+
+        public static final @NonNull Creator<GalileoSvHealth> CREATOR =
+                new Creator<GalileoSvHealth>() {
+                    @Override
+                    @NonNull
+                    public GalileoSvHealth createFromParcel(Parcel in) {
+                        final GalileoSvHealth.Builder galileoSvHealth = new Builder();
+                        galileoSvHealth.setDataValidityStatusE1b(in.readInt());
+                        galileoSvHealth.setSignalHealthStatusE1b(in.readInt());
+                        galileoSvHealth.setDataValidityStatusE5a(in.readInt());
+                        galileoSvHealth.setSignalHealthStatusE5a(in.readInt());
+                        galileoSvHealth.setDataValidityStatusE5b(in.readInt());
+                        galileoSvHealth.setSignalHealthStatusE5b(in.readInt());
+                        return galileoSvHealth.build();
+                    }
+
+                    @Override
+                    public GalileoSvHealth[] newArray(int size) {
+                        return new GalileoSvHealth[size];
+                    }
+                };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel parcel, int flags) {
+            parcel.writeInt(mDataValidityStatusE1b);
+            parcel.writeInt(mSignalHealthStatusE1b);
+            parcel.writeInt(mDataValidityStatusE5a);
+            parcel.writeInt(mSignalHealthStatusE5a);
+            parcel.writeInt(mDataValidityStatusE5b);
+            parcel.writeInt(mSignalHealthStatusE5b);
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            StringBuilder builder = new StringBuilder("GalileoSvHealth[");
+            builder.append("dataValidityStatusE1b = ").append(mDataValidityStatusE1b);
+            builder.append(", signalHealthStatusE1b = ").append(mSignalHealthStatusE1b);
+            builder.append(", dataValidityStatusE5a = ").append(mDataValidityStatusE5a);
+            builder.append(", signalHealthStatusE5a = ").append(mSignalHealthStatusE5a);
+            builder.append(", dataValidityStatusE5b = ").append(mDataValidityStatusE5b);
+            builder.append(", signalHealthStatusE5b = ").append(mSignalHealthStatusE5b);
+            builder.append("]");
+            return builder.toString();
+        }
+
+        /** Builder for {@link GalileoSvHealth}. */
+        public static final class Builder {
+            private int mDataValidityStatusE1b;
+            private int mSignalHealthStatusE1b;
+            private int mDataValidityStatusE5a;
+            private int mSignalHealthStatusE5a;
+            private int mDataValidityStatusE5b;
+            private int mSignalHealthStatusE5b;
+
+            /** Sets the E1-B data validity status. */
+            @NonNull
+            public Builder setDataValidityStatusE1b(
+                    @IntRange(from = 0, to = 1) int dataValidityStatusE1b) {
+                mDataValidityStatusE1b = dataValidityStatusE1b;
+                return this;
+            }
+
+            /** Sets the E1-B/C signal health status. */
+            @NonNull
+            public Builder setSignalHealthStatusE1b(
+                    @IntRange(from = 0, to = 3) int signalHealthStatusE1b) {
+                mSignalHealthStatusE1b = signalHealthStatusE1b;
+                return this;
+            }
+
+            /** Sets the E5a data validity status. */
+            @NonNull
+            public Builder setDataValidityStatusE5a(
+                    @IntRange(from = 0, to = 1) int dataValidityStatusE5a) {
+                mDataValidityStatusE5a = dataValidityStatusE5a;
+                return this;
+            }
+
+            /** Sets the E5a signal health status. */
+            @NonNull
+            public Builder setSignalHealthStatusE5a(
+                    @IntRange(from = 0, to = 3) int signalHealthStatusE5a) {
+                mSignalHealthStatusE5a = signalHealthStatusE5a;
+                return this;
+            }
+
+            /** Sets the E5b data validity status. */
+            @NonNull
+            public Builder setDataValidityStatusE5b(
+                    @IntRange(from = 0, to = 1) int dataValidityStatusE5b) {
+                mDataValidityStatusE5b = dataValidityStatusE5b;
+                return this;
+            }
+
+            /** Sets the E5b signal health status. */
+            @NonNull
+            public Builder setSignalHealthStatusE5b(
+                    @IntRange(from = 0, to = 3) int signalHealthStatusE5b) {
+                mSignalHealthStatusE5b = signalHealthStatusE5b;
+                return this;
+            }
+
+            /** Builds a {@link GalileoSvHealth}. */
+            @NonNull
+            public GalileoSvHealth build() {
+                return new GalileoSvHealth(this);
+            }
+        }
+    }
+
+    /**
+     * A class contains the set of parameters needed for Galileo satellite clock correction.
+     *
+     * <p>This is defined in Galileo-OS-SIS-ICD 5.1.3.
+     */
+    public static final class GalileoSatelliteClockModel implements Parcelable {
+
+        /**
+         * The type of the satellite clock.
+         *
+         * @hide
+         */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef({TYPE_UNDEFINED, TYPE_FNAV, TYPE_INAV})
+        public @interface SatelliteClockType {}
+
+        /**
+         * The following enumerations must be in sync with the values declared in
+         * GalileoSatelliteEphemeris.aidl.
+         */
+
+        /** The type of the satellite clock is unknown. */
+        public static final int TYPE_UNDEFINED = 0;
+
+        /** The type of the satellite clock is FNAV. */
+        public static final int TYPE_FNAV = 1;
+
+        /** The type of the satellite clock is INAV. */
+        public static final int TYPE_INAV = 2;
+
+        /**
+         * Time of the clock in seconds since Galileo epoch.
+         *
+         * <p>Corresponds to the 'Epoch' field within the 'SV/EPOCH/SV CLK' record of Galileo
+         * navigation message in RINEX 3.05 Table A8.
+         */
+        private final long mTimeOfClockSeconds;
+
+        /** SV clock bias correction coefficient in seconds. */
+        private double mAf0;
+
+        /** SV clock drift correction coefficient in seconds per second. */
+        private double mAf1;
+
+        /** SV clock drift rate correction coefficient in seconds per second squared. */
+        private double mAf2;
+
+        /**
+         * Broadcast group delay in seconds.
+         *
+         * <p>This is defined in Galileo-OS-SIS-ICD 5.1.5.
+         */
+        private double mBgdSeconds;
+
+        /**
+         * Signal in space accuracy in meters.
+         *
+         * <p>This is defined in Galileo-OS-SIS-ICD 5.1.12.
+         */
+        private double mSisaMeters;
+
+        /** Type of satellite clock . */
+        private final @SatelliteClockType int mSatelliteClockType;
+
+        private GalileoSatelliteClockModel(Builder builder) {
+            Preconditions.checkArgument(builder.mTimeOfClockSeconds >= 0);
+            Preconditions.checkArgumentInRange(builder.mAf0, -0.0625f, 0.0625f, "AF0");
+            Preconditions.checkArgumentInRange(builder.mAf1, -1.5e-8f, 1.5e-8f, "AF1");
+            Preconditions.checkArgumentInRange(builder.mAf2, -5.56e-17f, 5.56e-17f, "AF2");
+            Preconditions.checkArgumentInRange(
+                    builder.mBgdSeconds, -1.2e-7f, 1.2e-7f, "BgdSeconds");
+            Preconditions.checkArgument(builder.mSisaMeters >= 0.0f);
+            Preconditions.checkArgumentInRange(
+                    builder.mSatelliteClockType, TYPE_UNDEFINED, TYPE_INAV, "SatelliteClockType");
+            mTimeOfClockSeconds = builder.mTimeOfClockSeconds;
+            mAf0 = builder.mAf0;
+            mAf1 = builder.mAf1;
+            mAf2 = builder.mAf2;
+            mBgdSeconds = builder.mBgdSeconds;
+            mSisaMeters = builder.mSisaMeters;
+            mSatelliteClockType = builder.mSatelliteClockType;
+        }
+
+        /** Returns the time of the clock in seconds since Galileo epoch. */
+        @IntRange(from = 0)
+        public long getTimeOfClockSeconds() {
+            return mTimeOfClockSeconds;
+        }
+
+        /** Returns the SV clock bias correction coefficient in seconds. */
+        @FloatRange(from = -0.0625f, to = 0.0625f)
+        public double getAf0() {
+            return mAf0;
+        }
+
+        /** Returns the SV clock drift correction coefficient in seconds per second. */
+        @FloatRange(from = -1.5e-8f, to = 1.5e-8f)
+        public double getAf1() {
+            return mAf1;
+        }
+
+        /** Returns the SV clock drift rate correction coefficient in seconds per second squared. */
+        @FloatRange(from = -5.56e-17f, to = 5.56e-17f)
+        public double getAf2() {
+            return mAf2;
+        }
+
+        /** Returns the broadcast group delay in seconds. */
+        @FloatRange(from = -1.2e-7f, to = 1.2e-7f)
+        public double getBgdSeconds() {
+            return mBgdSeconds;
+        }
+
+        /** Returns the signal in space accuracy in meters. */
+        @FloatRange(from = 0.0f)
+        public double getSisaMeters() {
+            return mSisaMeters;
+        }
+
+        /** Returns the type of satellite clock. */
+        public @SatelliteClockType int getSatelliteClockType() {
+            return mSatelliteClockType;
+        }
+
+        public static final @NonNull Creator<GalileoSatelliteClockModel> CREATOR =
+                new Creator<GalileoSatelliteClockModel>() {
+                    @Override
+                    @NonNull
+                    public GalileoSatelliteClockModel createFromParcel(Parcel in) {
+                        final GalileoSatelliteClockModel.Builder galileoSatelliteClockModel =
+                                new Builder();
+                        galileoSatelliteClockModel.setTimeOfClockSeconds(in.readLong());
+                        galileoSatelliteClockModel.setAf0(in.readDouble());
+                        galileoSatelliteClockModel.setAf1(in.readDouble());
+                        galileoSatelliteClockModel.setAf2(in.readDouble());
+                        galileoSatelliteClockModel.setBgdSeconds(in.readDouble());
+                        galileoSatelliteClockModel.setSisaMeters(in.readDouble());
+                        galileoSatelliteClockModel.setSatelliteClockType(in.readInt());
+                        return galileoSatelliteClockModel.build();
+                    }
+
+                    @Override
+                    public GalileoSatelliteClockModel[] newArray(int size) {
+                        return new GalileoSatelliteClockModel[size];
+                    }
+                };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel parcel, int flags) {
+            parcel.writeLong(mTimeOfClockSeconds);
+            parcel.writeDouble(mAf0);
+            parcel.writeDouble(mAf1);
+            parcel.writeDouble(mAf2);
+            parcel.writeDouble(mBgdSeconds);
+            parcel.writeDouble(mSisaMeters);
+            parcel.writeInt(mSatelliteClockType);
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            StringBuilder builder = new StringBuilder("GalileoSatelliteClockModel[");
+            builder.append("timeOfClockSeconds = ").append(mTimeOfClockSeconds);
+            builder.append(", af0 = ").append(mAf0);
+            builder.append(", af1 = ").append(mAf1);
+            builder.append(", af2 = ").append(mAf2);
+            builder.append(", bgdSeconds = ").append(mBgdSeconds);
+            builder.append(", sisaMeters = ").append(mSisaMeters);
+            builder.append(", satelliteClockType = ").append(mSatelliteClockType);
+            builder.append("]");
+            return builder.toString();
+        }
+
+        /** Builder for {@link GalileoSatelliteClockModel}. */
+        public static final class Builder {
+            private long mTimeOfClockSeconds;
+            private double mAf0;
+            private double mAf1;
+            private double mAf2;
+            private double mBgdSeconds;
+            private double mSisaMeters;
+            private @SatelliteClockType int mSatelliteClockType;
+
+            /** Sets the time of the clock in seconds since Galileo epoch. */
+            @NonNull
+            public Builder setTimeOfClockSeconds(@IntRange(from = 0) long timeOfClockSeconds) {
+                mTimeOfClockSeconds = timeOfClockSeconds;
+                return this;
+            }
+
+            /** Sets the SV clock bias correction coefficient in seconds. */
+            @NonNull
+            public Builder setAf0(@FloatRange(from = -0.0625f, to = 0.0625f) double af0) {
+                mAf0 = af0;
+                return this;
+            }
+
+            /** Sets the SV clock drift correction coefficient in seconds per second. */
+            @NonNull
+            public Builder setAf1(@FloatRange(from = -1.5e-8f, to = 1.5e-8f) double af1) {
+                mAf1 = af1;
+                return this;
+            }
+
+            /**
+             * Sets the SV clock drift rate correction coefficient in seconds per second squared.
+             */
+            @NonNull
+            public Builder setAf2(@FloatRange(from = -5.56e-17f, to = 5.56e-17f) double af2) {
+                mAf2 = af2;
+                return this;
+            }
+
+            /** Sets the broadcast group delay in seconds. */
+            @NonNull
+            public Builder setBgdSeconds(
+                    @FloatRange(from = -1.2e-7f, to = 1.2e-7f) double bgdSeconds) {
+                mBgdSeconds = bgdSeconds;
+                return this;
+            }
+
+            /** Sets the signal in space accuracy in meters. */
+            @NonNull
+            public Builder setSisaMeters(@FloatRange(from = 0.0f) double sisaMeters) {
+                mSisaMeters = sisaMeters;
+                return this;
+            }
+
+            /** Sets the type of satellite clock. */
+            @NonNull
+            public Builder setSatelliteClockType(@SatelliteClockType int satelliteClockType) {
+                mSatelliteClockType = satelliteClockType;
+                return this;
+            }
+
+            /**
+             * Builds a {@link GalileoSatelliteClockModel} instance as specified by this builder.
+             */
+            @NonNull
+            public GalileoSatelliteClockModel build() {
+                return new GalileoSatelliteClockModel(this);
+            }
+        }
+    }
+}
diff --git a/location/java/android/location/GlonassAlmanac.java b/location/java/android/location/GlonassAlmanac.java
new file mode 100644
index 0000000..861dc5d
--- /dev/null
+++ b/location/java/android/location/GlonassAlmanac.java
@@ -0,0 +1,418 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class contains Glonass almanac data.
+ *
+ * <p>This is defined in Glonass ICD v5.1 section 4.5.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GlonassAlmanac implements Parcelable {
+
+    /** Almanac issue date in milliseconds (UTC) */
+    private final long mIssueDateMillis;
+
+    /** List of GlonassSatelliteAlmanacs. */
+    @NonNull private final List<GlonassSatelliteAlmanac> mSatelliteAlmanacs;
+
+    /**
+     * Constructor for GlonassAlmanac.
+     *
+     * @param issueDateMillis The almanac issue date in milliseconds (UTC).
+     * @param satelliteAlmanacs The list of GlonassSatelliteAlmanac.
+     */
+    public GlonassAlmanac(
+            @IntRange(from = 0) long issueDateMillis,
+            @NonNull List<GlonassSatelliteAlmanac> satelliteAlmanacs) {
+        Preconditions.checkArgument(issueDateMillis >= 0);
+        Preconditions.checkNotNull(satelliteAlmanacs, "satelliteAlmanacs cannot be null");
+        mIssueDateMillis = issueDateMillis;
+        mSatelliteAlmanacs = Collections.unmodifiableList(new ArrayList<>(satelliteAlmanacs));
+    }
+
+    /** Returns the almanac issue date in milliseconds (UTC). */
+    @IntRange(from = 0)
+    public long getIssueDateMillis() {
+        return mIssueDateMillis;
+    }
+
+    /** Returns the list of GlonassSatelliteAlmanacs. */
+    @NonNull
+    public List<GlonassSatelliteAlmanac> getSatelliteAlmanacs() {
+        return mSatelliteAlmanacs;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeLong(mIssueDateMillis);
+        dest.writeTypedList(mSatelliteAlmanacs);
+    }
+
+    public static final @NonNull Parcelable.Creator<GlonassAlmanac> CREATOR =
+            new Parcelable.Creator<GlonassAlmanac>() {
+                @Override
+                public GlonassAlmanac createFromParcel(@NonNull Parcel in) {
+                    long issueDateMillis = in.readLong();
+                    List<GlonassSatelliteAlmanac> satelliteAlmanacs = new ArrayList<>();
+                    in.readTypedList(satelliteAlmanacs, GlonassSatelliteAlmanac.CREATOR);
+                    return new GlonassAlmanac(issueDateMillis, satelliteAlmanacs);
+                }
+
+                @Override
+                public GlonassAlmanac[] newArray(int size) {
+                    return new GlonassAlmanac[size];
+                }
+            };
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("GlonassAlmanac[");
+        builder.append("issueDateMillis = ").append(mIssueDateMillis);
+        builder.append(", satelliteAlmanacs = ").append(mSatelliteAlmanacs);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /**
+     * A class contains Glonass satellite almanac data.
+     *
+     * <p>This is defined in Glonass ICD v5.1 section 4.5.
+     */
+    public static final class GlonassSatelliteAlmanac implements Parcelable {
+        /** Slot number. */
+        private final int mSlotNumber;
+
+        /** Satellite health information (0=healthy, 1=unhealthy). */
+        private final int mSvHealth;
+
+        /** Frequency channel number. */
+        private final int mFreqChannel;
+
+        /** Coarse value of satellite time correction to GLONASS time in seconds. */
+        private final double mTau;
+
+        /** Time of first ascending node passage of satellite in seconds. */
+        private final double mTLambda;
+
+        /** Longitude of the first ascending node in semi-circles. */
+        private final double mLambda;
+
+        /** Correction to the mean value of inclination in semi-circles. */
+        private final double mDeltaI;
+
+        /** Correction to the mean value of the draconian period in seconds per orbital period */
+        private final double mDeltaT;
+
+        /** Rate of change of draconian period in seconds per orbital period squared. */
+        private final double mDeltaTDot;
+
+        /** Eccentricity. */
+        private final double mEccentricity;
+
+        /** Argument of perigee in radians. */
+        private final double mOmega;
+
+        private GlonassSatelliteAlmanac(Builder builder) {
+            // Allow slotNumber beyond the range to support potential future extensibility.
+            Preconditions.checkArgument(builder.mSlotNumber >= 1);
+            // Allow svHealth beyond the range to support potential future extensibility.
+            Preconditions.checkArgument(builder.mSvHealth >= 0);
+            Preconditions.checkArgumentInRange(builder.mFreqChannel, 0, 31, "FreqChannel");
+            Preconditions.checkArgumentInRange(builder.mTau, -1.9e-3f, 1.9e-3f, "Tau");
+            Preconditions.checkArgumentInRange(builder.mTLambda, 0.0f, 44100.0f, "TLambda");
+            Preconditions.checkArgumentInRange(builder.mLambda, -1.0f, 1.0f, "Lambda");
+            Preconditions.checkArgumentInRange(builder.mDeltaI, -0.067f, 0.067f, "DeltaI");
+            Preconditions.checkArgumentInRange(builder.mDeltaT, -3600.0f, 3600.0f, "DeltaT");
+            Preconditions.checkArgumentInRange(builder.mDeltaTDot, -0.004f, 0.004f, "DeltaTDot");
+            Preconditions.checkArgumentInRange(builder.mEccentricity, 0.0f, 0.03f, "Eccentricity");
+            Preconditions.checkArgumentInRange(builder.mOmega, -1.0f, 1.0f, "Omega");
+            mSlotNumber = builder.mSlotNumber;
+            mSvHealth = builder.mSvHealth;
+            mFreqChannel = builder.mFreqChannel;
+            mTau = builder.mTau;
+            mTLambda = builder.mTLambda;
+            mLambda = builder.mLambda;
+            mDeltaI = builder.mDeltaI;
+            mDeltaT = builder.mDeltaT;
+            mDeltaTDot = builder.mDeltaTDot;
+            mEccentricity = builder.mEccentricity;
+            mOmega = builder.mOmega;
+        }
+
+        /** Returns the slot number. */
+        @IntRange(from = 1, to = 25)
+        public int getSlotNumber() {
+            return mSlotNumber;
+        }
+
+        /** Returns the Satellite health information (0=healthy, 1=unhealthy). */
+        @IntRange(from = 0, to = 1)
+        public int getSvHealth() {
+            return mSvHealth;
+        }
+
+        /** Returns the frequency channel number. */
+        @IntRange(from = 0, to = 31)
+        public int getFreqChannel() {
+            return mFreqChannel;
+        }
+
+        /** Returns the coarse value of satellite time correction to GLONASS time in seconds. */
+        @FloatRange(from = -1.9e-3f, to = 1.9e-3f)
+        public double getTau() {
+            return mTau;
+        }
+
+        /** Returns the time of first ascending node passage of satellite in seconds. */
+        @FloatRange(from = 0.0f, to = 44100.0f)
+        public double getTLambda() {
+            return mTLambda;
+        }
+
+        /** Returns the longitude of the first ascending node in semi-circles. */
+        @FloatRange(from = -1.0f, to = 1.0f)
+        public double getLambda() {
+            return mLambda;
+        }
+
+        /** Returns the correction to the mean value of inclination in semi-circles. */
+        @FloatRange(from = -0.067f, to = 0.067f)
+        public double getDeltaI() {
+            return mDeltaI;
+        }
+
+        /**
+         * Returns the correction to the mean value of the draconian period in seconds per orbital
+         * period
+         */
+        @FloatRange(from = -3600.0f, to = 3600.0f)
+        public double getDeltaT() {
+            return mDeltaT;
+        }
+
+        /** Returns the rate of change of draconian period in seconds per orbital period squared. */
+        @FloatRange(from = -0.004f, to = 0.004f)
+        public double getDeltaTDot() {
+            return mDeltaTDot;
+        }
+
+        /** Returns the eccentricity. */
+        @FloatRange(from = 0.0f, to = 0.03f)
+        public double getEccentricity() {
+            return mEccentricity;
+        }
+
+        /** Returns the argument of perigee in radians. */
+        @FloatRange(from = -1.0f, to = 1.0f)
+        public double getOmega() {
+            return mOmega;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel dest, int flags) {
+            dest.writeInt(mSlotNumber);
+            dest.writeInt(mSvHealth);
+            dest.writeInt(mFreqChannel);
+            dest.writeDouble(mTau);
+            dest.writeDouble(mTLambda);
+            dest.writeDouble(mLambda);
+            dest.writeDouble(mDeltaI);
+            dest.writeDouble(mDeltaT);
+            dest.writeDouble(mDeltaTDot);
+            dest.writeDouble(mEccentricity);
+            dest.writeDouble(mOmega);
+        }
+
+        public static final @NonNull Parcelable.Creator<GlonassSatelliteAlmanac> CREATOR =
+                new Parcelable.Creator<GlonassSatelliteAlmanac>() {
+                    @Override
+                    public GlonassSatelliteAlmanac createFromParcel(@NonNull Parcel source) {
+                        return new GlonassSatelliteAlmanac.Builder()
+                                .setSlotNumber(source.readInt())
+                                .setSvHealth(source.readInt())
+                                .setFreqChannel(source.readInt())
+                                .setTau(source.readDouble())
+                                .setTLambda(source.readDouble())
+                                .setLambda(source.readDouble())
+                                .setDeltaI(source.readDouble())
+                                .setDeltaT(source.readDouble())
+                                .setDeltaTDot(source.readDouble())
+                                .setEccentricity(source.readDouble())
+                                .setOmega(source.readDouble())
+                                .build();
+                    }
+
+                    @Override
+                    public GlonassSatelliteAlmanac[] newArray(int size) {
+                        return new GlonassSatelliteAlmanac[size];
+                    }
+                };
+
+        @Override
+        @NonNull
+        public String toString() {
+            StringBuilder builder = new StringBuilder("GlonassSatelliteAlmanac[");
+            builder.append("slotNumber = ").append(mSlotNumber);
+            builder.append(", svHealth = ").append(mSvHealth);
+            builder.append(", freqChannel = ").append(mFreqChannel);
+            builder.append(", tau = ").append(mTau);
+            builder.append(", tLambda = ").append(mTLambda);
+            builder.append(", lambda = ").append(mLambda);
+            builder.append(", deltaI = ").append(mDeltaI);
+            builder.append(", deltaT = ").append(mDeltaT);
+            builder.append(", deltaTDot = ").append(mDeltaTDot);
+            builder.append(", eccentricity = ").append(mEccentricity);
+            builder.append(", omega = ").append(mOmega);
+            builder.append("]");
+            return builder.toString();
+        }
+
+        /** Builder for {@link GlonassSatelliteAlmanac}. */
+        public static final class Builder {
+            private int mSlotNumber;
+            private int mSvHealth;
+            private int mFreqChannel;
+            private double mTau;
+            private double mTLambda;
+            private double mLambda;
+            private double mDeltaI;
+            private double mDeltaT;
+            private double mDeltaTDot;
+            private double mEccentricity;
+            private double mOmega;
+
+            /** Sets the slot number. */
+            @NonNull
+            public Builder setSlotNumber(@IntRange(from = 1, to = 25) int slotNumber) {
+                mSlotNumber = slotNumber;
+                return this;
+            }
+
+            /** Sets the Satellite health information (0=healthy, 1=unhealthy). */
+            @NonNull
+            public Builder setSvHealth(@IntRange(from = 0, to = 1) int svHealth) {
+                mSvHealth = svHealth;
+                return this;
+            }
+
+            /** Sets the frequency channel number. */
+            @NonNull
+            public Builder setFreqChannel(@IntRange(from = 0, to = 31) int freqChannel) {
+                mFreqChannel = freqChannel;
+                return this;
+            }
+
+            /** Sets the coarse value of satellite time correction to GLONASS time in seconds. */
+            @NonNull
+            public Builder setTau(@FloatRange(from = -1.9e-3f, to = 1.9e-3f) double tau) {
+                mTau = tau;
+                return this;
+            }
+
+            /** Sets the time of first ascending node passage of satellite in seconds. */
+            @NonNull
+            public Builder setTLambda(@FloatRange(from = 0.0f, to = 44100.0f) double tLambda) {
+                mTLambda = tLambda;
+                return this;
+            }
+
+            /** Sets the longitude of the first ascending node in semi-circles. */
+            @NonNull
+            public Builder setLambda(@FloatRange(from = -1.0f, to = 1.0f) double lambda) {
+                mLambda = lambda;
+                return this;
+            }
+
+            /** Sets the correction to the mean value of inclination in semi-circles. */
+            @NonNull
+            public Builder setDeltaI(@FloatRange(from = -0.067f, to = 0.067f) double deltaI) {
+                mDeltaI = deltaI;
+                return this;
+            }
+
+            /**
+             * Sets the correction to the mean value of the draconian period in seconds per orbital
+             * period.
+             */
+            @NonNull
+            public Builder setDeltaT(@FloatRange(from = -3600.0f, to = 3600.0f) double deltaT) {
+                mDeltaT = deltaT;
+                return this;
+            }
+
+            /**
+             * Sets the rate of change of draconian period in seconds per orbital period squared.
+             */
+            @NonNull
+            public Builder setDeltaTDot(@FloatRange(from = -0.004f, to = 0.004f) double deltaTDot) {
+                mDeltaTDot = deltaTDot;
+                return this;
+            }
+
+            /** Sets the eccentricity. */
+            @NonNull
+            public Builder setEccentricity(
+                    @FloatRange(from = 0.0f, to = 0.03f) double eccentricity) {
+                mEccentricity = eccentricity;
+                return this;
+            }
+
+            /** Sets the argument of perigee in radians. */
+            @NonNull
+            public Builder setOmega(@FloatRange(from = -1.0f, to = 1.0f) double omega) {
+                mOmega = omega;
+                return this;
+            }
+
+            /** Builds a {@link GlonassSatelliteAlmanac}. */
+            @NonNull
+            public GlonassSatelliteAlmanac build() {
+                return new GlonassSatelliteAlmanac(this);
+            }
+        }
+    }
+}
diff --git a/location/java/android/location/GlonassAssistance.java b/location/java/android/location/GlonassAssistance.java
new file mode 100644
index 0000000..cc08201
--- /dev/null
+++ b/location/java/android/location/GlonassAssistance.java
@@ -0,0 +1,213 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.location.GnssAssistance.GnssSatelliteCorrections;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class contains Glonass assistance.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GlonassAssistance implements Parcelable {
+
+    /** The Glonass almanac. */
+    @Nullable private final GlonassAlmanac mAlmanac;
+
+    /** The UTC model. */
+    @Nullable private final UtcModel mUtcModel;
+
+    /** The list of time models. */
+    @NonNull private final List<TimeModel> mTimeModels;
+
+    /** The list of Glonass ephemeris. */
+    @NonNull private final List<GlonassSatelliteEphemeris> mSatelliteEphemeris;
+
+    /** The list of Glonass satellite corrections. */
+    @NonNull private final List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+    private GlonassAssistance(Builder builder) {
+        mAlmanac = builder.mAlmanac;
+        mUtcModel = builder.mUtcModel;
+        if (builder.mTimeModels != null) {
+            mTimeModels = Collections.unmodifiableList(new ArrayList<>(builder.mTimeModels));
+        } else {
+            mTimeModels = new ArrayList<>();
+        }
+        if (builder.mSatelliteEphemeris != null) {
+            mSatelliteEphemeris =
+                    Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteEphemeris));
+        } else {
+            mSatelliteEphemeris = new ArrayList<>();
+        }
+        if (builder.mSatelliteCorrections != null) {
+            mSatelliteCorrections =
+                    Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteCorrections));
+        } else {
+            mSatelliteCorrections = new ArrayList<>();
+        }
+    }
+
+    /** Returns the Glonass almanac. */
+    @Nullable
+    public GlonassAlmanac getAlmanac() {
+        return mAlmanac;
+    }
+
+    /** Returns the UTC model. */
+    @Nullable
+    public UtcModel getUtcModel() {
+        return mUtcModel;
+    }
+
+    /** Returns the list of time models. */
+    @NonNull
+    public List<TimeModel> getTimeModels() {
+        return mTimeModels;
+    }
+
+    /** Returns the list of Glonass satellite ephemeris. */
+    @NonNull
+    public List<GlonassSatelliteEphemeris> getSatelliteEphemeris() {
+        return mSatelliteEphemeris;
+    }
+
+    /** Returns the list of Glonass satellite corrections. */
+    @NonNull
+    public List<GnssSatelliteCorrections> getSatelliteCorrections() {
+        return mSatelliteCorrections;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeTypedObject(mAlmanac, flags);
+        dest.writeTypedObject(mUtcModel, flags);
+        dest.writeTypedList(mTimeModels);
+        dest.writeTypedList(mSatelliteEphemeris);
+        dest.writeTypedList(mSatelliteCorrections);
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("GlonassAssistance[");
+        builder.append("almanac = ").append(mAlmanac);
+        builder.append(", utcModel = ").append(mUtcModel);
+        builder.append(", timeModels = ").append(mTimeModels);
+        builder.append(", satelliteEphemeris = ").append(mSatelliteEphemeris);
+        builder.append(", satelliteCorrections = ").append(mSatelliteCorrections);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    public static final @NonNull Creator<GlonassAssistance> CREATOR =
+            new Creator<GlonassAssistance>() {
+                @Override
+                public GlonassAssistance createFromParcel(Parcel in) {
+                    return new GlonassAssistance.Builder()
+                            .setAlmanac(in.readTypedObject(GlonassAlmanac.CREATOR))
+                            .setUtcModel(in.readTypedObject(UtcModel.CREATOR))
+                            .setTimeModels(in.createTypedArrayList(TimeModel.CREATOR))
+                            .setSatelliteEphemeris(
+                                    in.createTypedArrayList(GlonassSatelliteEphemeris.CREATOR))
+                            .setSatelliteCorrections(
+                                    in.createTypedArrayList(GnssSatelliteCorrections.CREATOR))
+                            .build();
+                }
+
+                @Override
+                public GlonassAssistance[] newArray(int size) {
+                    return new GlonassAssistance[size];
+                }
+            };
+
+    /** Builder for {@link GlonassAssistance}. */
+    public static final class Builder {
+        private GlonassAlmanac mAlmanac;
+        private UtcModel mUtcModel;
+        private List<TimeModel> mTimeModels;
+        private List<GlonassSatelliteEphemeris> mSatelliteEphemeris;
+        private List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+        /** Sets the Glonass almanac. */
+        @NonNull
+        public Builder setAlmanac(
+                @Nullable @SuppressLint("NullableCollection") GlonassAlmanac almanac) {
+            mAlmanac = almanac;
+            return this;
+        }
+
+        /** Sets the UTC model. */
+        @NonNull
+        public Builder setUtcModel(
+                @Nullable @SuppressLint("NullableCollection") UtcModel utcModel) {
+            mUtcModel = utcModel;
+            return this;
+        }
+
+        /** Sets the list of time models. */
+        @NonNull
+        public Builder setTimeModels(
+                @Nullable @SuppressLint("NullableCollection") List<TimeModel> timeModels) {
+            mTimeModels = timeModels;
+            return this;
+        }
+
+        /** Sets the list of Glonass satellite ephemeris. */
+        @NonNull
+        public Builder setSatelliteEphemeris(
+                @Nullable @SuppressLint("NullableCollection")
+                        List<GlonassSatelliteEphemeris> satelliteEphemeris) {
+            mSatelliteEphemeris = satelliteEphemeris;
+            return this;
+        }
+
+        /** Sets the list of Glonass satellite corrections. */
+        @NonNull
+        public Builder setSatelliteCorrections(
+                @Nullable @SuppressLint("NullableCollection")
+                        List<GnssSatelliteCorrections> satelliteCorrections) {
+            mSatelliteCorrections = satelliteCorrections;
+            return this;
+        }
+
+        /** Builds the {@link GlonassAssistance}. */
+        @NonNull
+        public GlonassAssistance build() {
+            return new GlonassAssistance(this);
+        }
+    }
+}
diff --git a/location/java/android/location/GlonassSatelliteEphemeris.java b/location/java/android/location/GlonassSatelliteEphemeris.java
new file mode 100644
index 0000000..77a6ebb
--- /dev/null
+++ b/location/java/android/location/GlonassSatelliteEphemeris.java
@@ -0,0 +1,623 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains ephemeris parameters specific to Glonass satellites.
+ *
+ * <p>This is defined in RINEX 3.05 APPENDIX 10 and Glonass ICD v5.1 section 4.4.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GlonassSatelliteEphemeris implements Parcelable {
+
+    /** L1/Satellite system (R), satellite number (slot number in sat. constellation). */
+    private final int mSlotNumber;
+
+    /** Health state (0=healthy, 1=unhealthy). */
+    private final int mHealthState;
+
+    /** Message frame time in seconds of the UTC week (tk+nd*86400). */
+    private final double mFrameTimeSeconds;
+
+    /** Age of current information in days (E). */
+    private final int mAgeInDays;
+
+    /** Satellite clock model. */
+    @NonNull private final GlonassSatelliteClockModel mSatelliteClockModel;
+
+    /** Satellite orbit model. */
+    @NonNull private final GlonassSatelliteOrbitModel mSatelliteOrbitModel;
+
+    private GlonassSatelliteEphemeris(Builder builder) {
+        // Allow SlotNumber beyond the range to support potential future extensibility.
+        Preconditions.checkArgument(builder.mSlotNumber >= 1);
+        // Allow HealthState beyond the range to support potential future extensibility.
+        Preconditions.checkArgument(builder.mHealthState >= 0);
+        Preconditions.checkArgument(builder.mFrameTimeSeconds >= 0.0f);
+        Preconditions.checkArgumentInRange(builder.mAgeInDays, 0, 31, "AgeInDays");
+        Preconditions.checkNotNull(
+                builder.mSatelliteClockModel, "SatelliteClockModel cannot be null");
+        Preconditions.checkNotNull(
+                builder.mSatelliteOrbitModel, "SatelliteOrbitModel cannot be null");
+        mSlotNumber = builder.mSlotNumber;
+        mHealthState = builder.mHealthState;
+        mFrameTimeSeconds = builder.mFrameTimeSeconds;
+        mAgeInDays = builder.mAgeInDays;
+        mSatelliteClockModel = builder.mSatelliteClockModel;
+        mSatelliteOrbitModel = builder.mSatelliteOrbitModel;
+    }
+
+    /**
+     * Returns the L1/Satellite system (R), satellite number (slot number in sat. constellation).
+     */
+    @IntRange(from = 1, to = 25)
+    public int getSlotNumber() {
+        return mSlotNumber;
+    }
+
+    /** Returns the health state (0=healthy, 1=unhealthy). */
+    @IntRange(from = 0, to = 1)
+    public int getHealthState() {
+        return mHealthState;
+    }
+
+    /** Returns the message frame time in seconds of the UTC week (tk+nd*86400). */
+    @FloatRange(from = 0.0f)
+    public double getFrameTimeSeconds() {
+        return mFrameTimeSeconds;
+    }
+
+    /** Returns the age of current information in days (E). */
+    @IntRange(from = 0, to = 31)
+    public int getAgeInDays() {
+        return mAgeInDays;
+    }
+
+    /** Returns the satellite clock model. */
+    @NonNull
+    public GlonassSatelliteClockModel getSatelliteClockModel() {
+        return mSatelliteClockModel;
+    }
+
+    /** Returns the satellite orbit model. */
+    @NonNull
+    public GlonassSatelliteOrbitModel getSatelliteOrbitModel() {
+        return mSatelliteOrbitModel;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mSlotNumber);
+        dest.writeInt(mHealthState);
+        dest.writeDouble(mFrameTimeSeconds);
+        dest.writeInt(mAgeInDays);
+        dest.writeTypedObject(mSatelliteClockModel, flags);
+        dest.writeTypedObject(mSatelliteOrbitModel, flags);
+    }
+
+    public static final @NonNull Parcelable.Creator<GlonassSatelliteEphemeris> CREATOR =
+            new Parcelable.Creator<GlonassSatelliteEphemeris>() {
+                @Override
+                public GlonassSatelliteEphemeris createFromParcel(@NonNull Parcel source) {
+                    return new GlonassSatelliteEphemeris.Builder()
+                            .setSlotNumber(source.readInt())
+                            .setHealthState(source.readInt())
+                            .setFrameTimeSeconds(source.readDouble())
+                            .setAgeInDays(source.readInt())
+                            .setSatelliteClockModel(
+                                    source.readTypedObject(GlonassSatelliteClockModel.CREATOR))
+                            .setSatelliteOrbitModel(
+                                    source.readTypedObject(GlonassSatelliteOrbitModel.CREATOR))
+                            .build();
+                }
+
+                @Override
+                public GlonassSatelliteEphemeris[] newArray(int size) {
+                    return new GlonassSatelliteEphemeris[size];
+                }
+            };
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("GlonassSatelliteEphemeris[");
+        builder.append("slotNumber = ").append(mSlotNumber);
+        builder.append(", healthState = ").append(mHealthState);
+        builder.append(", frameTimeSeconds = ").append(mFrameTimeSeconds);
+        builder.append(", ageInDays = ").append(mAgeInDays);
+        builder.append(", satelliteClockModel = ").append(mSatelliteClockModel);
+        builder.append(", satelliteOrbitModel = ").append(mSatelliteOrbitModel);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /** Builder for {@link GlonassSatelliteEphemeris}. */
+    public static final class Builder {
+        private int mSlotNumber;
+        private int mHealthState;
+        private double mFrameTimeSeconds;
+        private int mAgeInDays;
+        private GlonassSatelliteClockModel mSatelliteClockModel;
+        private GlonassSatelliteOrbitModel mSatelliteOrbitModel;
+
+        /**
+         * Sets the L1/Satellite system (R), satellite number (slot number in sat. constellation).
+         */
+        @NonNull
+        public Builder setSlotNumber(@IntRange(from = 1, to = 25) int slotNumber) {
+            mSlotNumber = slotNumber;
+            return this;
+        }
+
+        /** Sets the health state (0=healthy, 1=unhealthy). */
+        @NonNull
+        public Builder setHealthState(@IntRange(from = 0, to = 1) int healthState) {
+            mHealthState = healthState;
+            return this;
+        }
+
+        /** Sets the message frame time in seconds of the UTC week (tk+nd*86400). */
+        @NonNull
+        public Builder setFrameTimeSeconds(@FloatRange(from = 0.0f) double frameTimeSeconds) {
+            mFrameTimeSeconds = frameTimeSeconds;
+            return this;
+        }
+
+        /** Sets the age of current information in days (E). */
+        @NonNull
+        public Builder setAgeInDays(@IntRange(from = 0, to = 31) int ageInDays) {
+            mAgeInDays = ageInDays;
+            return this;
+        }
+
+        /** Sets the satellite clock model. */
+        @NonNull
+        public Builder setSatelliteClockModel(
+                @NonNull GlonassSatelliteClockModel satelliteClockModel) {
+            mSatelliteClockModel = satelliteClockModel;
+            return this;
+        }
+
+        /** Sets the satellite orbit model. */
+        @NonNull
+        public Builder setSatelliteOrbitModel(
+                @NonNull GlonassSatelliteOrbitModel satelliteOrbitModel) {
+            mSatelliteOrbitModel = satelliteOrbitModel;
+            return this;
+        }
+
+        /** Builds a {@link GlonassSatelliteEphemeris}. */
+        @NonNull
+        public GlonassSatelliteEphemeris build() {
+            return new GlonassSatelliteEphemeris(this);
+        }
+    }
+
+    /**
+     * A class contains the set of parameters needed for Glonass satellite clock correction.
+     *
+     * <p>This is defined in RINEX 3.05 APPENDIX 10 and Glonass ICD v5.1 section 4.4.
+     */
+    public static final class GlonassSatelliteClockModel implements Parcelable {
+        /**
+         * Time of the clock in seconds (UTC)
+         *
+         * <p>Corresponds to the 'Epoch' field within the 'SV/EPOCH/SV CLK' record of Glonass
+         * navigation message in RINEX 3.05 Table A10.
+         */
+        private final long mTimeOfClockSeconds;
+
+        /** Clock bias in seconds (-TauN). */
+        private final double mClockBias;
+
+        /** Frequency bias (+GammaN). */
+        private final double mFrequencyBias;
+
+        /** Frequency number. */
+        private final int mFrequencyNumber;
+
+        private GlonassSatelliteClockModel(Builder builder) {
+            Preconditions.checkArgument(builder.mTimeOfClockSeconds >= 0);
+            Preconditions.checkArgumentInRange(builder.mClockBias, -0.002f, 0.002f, "ClockBias");
+            Preconditions.checkArgumentInRange(
+                    builder.mFrequencyBias, -9.32e-10f, 9.32e-10f, "FrequencyBias");
+            Preconditions.checkArgumentInRange(builder.mFrequencyNumber, -7, 6, "FrequencyNumber");
+            mTimeOfClockSeconds = builder.mTimeOfClockSeconds;
+            mClockBias = builder.mClockBias;
+            mFrequencyBias = builder.mFrequencyBias;
+            mFrequencyNumber = builder.mFrequencyNumber;
+        }
+
+        /** Returns the time of clock in seconds (UTC). */
+        @IntRange(from = 0)
+        public long getTimeOfClockSeconds() {
+            return mTimeOfClockSeconds;
+        }
+
+        /** Returns the clock bias in seconds (-TauN). */
+        @FloatRange(from = -0.002f, to = 0.002f)
+        public double getClockBias() {
+            return mClockBias;
+        }
+
+        /** Returns the frequency bias (+GammaN). */
+        @FloatRange(from = -9.32e-10f, to = 9.32e-10f)
+        public double getFrequencyBias() {
+            return mFrequencyBias;
+        }
+
+        /** Returns the frequency number. */
+        @IntRange(from = -7, to = 6)
+        public int getFrequencyNumber() {
+            return mFrequencyNumber;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel dest, int flags) {
+            dest.writeLong(mTimeOfClockSeconds);
+            dest.writeDouble(mClockBias);
+            dest.writeDouble(mFrequencyBias);
+            dest.writeInt(mFrequencyNumber);
+        }
+
+        public static final @NonNull Parcelable.Creator<GlonassSatelliteClockModel> CREATOR =
+                new Parcelable.Creator<GlonassSatelliteClockModel>() {
+                    @Override
+                    public GlonassSatelliteClockModel createFromParcel(@NonNull Parcel source) {
+                        return new GlonassSatelliteClockModel.Builder()
+                                .setTimeOfClockSeconds(source.readLong())
+                                .setClockBias(source.readDouble())
+                                .setFrequencyBias(source.readDouble())
+                                .setFrequencyNumber(source.readInt())
+                                .build();
+                    }
+
+                    @Override
+                    public GlonassSatelliteClockModel[] newArray(int size) {
+                        return new GlonassSatelliteClockModel[size];
+                    }
+                };
+
+        @Override
+        @NonNull
+        public String toString() {
+            StringBuilder builder = new StringBuilder("GlonassSatelliteClockModel[");
+            builder.append("timeOfClockSeconds = ").append(mTimeOfClockSeconds);
+            builder.append(", clockBias = ").append(mClockBias);
+            builder.append(", frequencyBias = ").append(mFrequencyBias);
+            builder.append(", frequencyNumber = ").append(mFrequencyNumber);
+            builder.append("]");
+            return builder.toString();
+        }
+
+        /** Builder for {@link GlonassSatelliteClockModel}. */
+        public static final class Builder {
+            private long mTimeOfClockSeconds;
+            private double mClockBias;
+            private double mFrequencyBias;
+            private int mFrequencyNumber;
+
+            /** Sets the time of clock in seconds (UTC). */
+            @NonNull
+            public Builder setTimeOfClockSeconds(@IntRange(from = 0) long timeOfClockSeconds) {
+                mTimeOfClockSeconds = timeOfClockSeconds;
+                return this;
+            }
+
+            /** Sets the clock bias in seconds (-TauN). */
+            @NonNull
+            public Builder setClockBias(@FloatRange(from = -0.002f, to = 0.002f) double clockBias) {
+                mClockBias = clockBias;
+                return this;
+            }
+
+            /** Sets the frequency bias (+GammaN). */
+            @NonNull
+            public Builder setFrequencyBias(
+                    @FloatRange(from = -9.32e-10f, to = 9.32e-10f) double frequencyBias) {
+                mFrequencyBias = frequencyBias;
+                return this;
+            }
+
+            /** Sets the frequency number. */
+            @NonNull
+            public Builder setFrequencyNumber(@IntRange(from = -7, to = 6) int frequencyNumber) {
+                mFrequencyNumber = frequencyNumber;
+                return this;
+            }
+
+            /** Builds a {@link GlonassSatelliteClockModel}. */
+            @NonNull
+            public GlonassSatelliteClockModel build() {
+                return new GlonassSatelliteClockModel(this);
+            }
+        }
+    }
+
+    /**
+     * A class contains the set of parameters needed for Glonass satellite orbit correction.
+     *
+     * <p>This is defined in RINEX 3.05 APPENDIX 10 and Glonass ICD v5.1 section 4.4.
+     */
+    public static final class GlonassSatelliteOrbitModel implements Parcelable {
+        /** X position in kilometers. */
+        private final double mX;
+
+        /** X velocity in kilometers per second. */
+        private final double mXDot;
+
+        /** X acceleration in kilometers per second squared. */
+        private final double mXAccel;
+
+        /** Y position in kilometers. */
+        private final double mY;
+
+        /** Y velocity in kilometers per second. */
+        private final double mYDot;
+
+        /** Y acceleration in kilometers per second squared. */
+        private final double mYAccel;
+
+        /** Z position in kilometers. */
+        private final double mZ;
+
+        /** Z velocity in kilometers per second. */
+        private final double mZDot;
+
+        /** Z acceleration in kilometers per second squared. */
+        private final double mZAccel;
+
+        private GlonassSatelliteOrbitModel(Builder builder) {
+            Preconditions.checkArgumentInRange(builder.mX, -2.7e4f, 2.7e4f, "X");
+            Preconditions.checkArgumentInRange(builder.mXDot, -4.3f, 4.3f, "XDot");
+            Preconditions.checkArgumentInRange(builder.mXAccel, -6.2e-9f, 6.2e-9f, "XAccel");
+            Preconditions.checkArgumentInRange(builder.mY, -2.7e4f, 2.7e4f, "Y");
+            Preconditions.checkArgumentInRange(builder.mYDot, -4.3f, 4.3f, "YDot");
+            Preconditions.checkArgumentInRange(builder.mYAccel, -6.2e-9f, 6.2e-9f, "YAccel");
+            Preconditions.checkArgumentInRange(builder.mZ, -2.7e4f, 2.7e4f, "Z");
+            Preconditions.checkArgumentInRange(builder.mZDot, -4.3f, 4.3f, "ZDot");
+            Preconditions.checkArgumentInRange(builder.mZAccel, -6.2e-9f, 6.2e-9f, "ZAccel");
+            mX = builder.mX;
+            mXDot = builder.mXDot;
+            mXAccel = builder.mXAccel;
+            mY = builder.mY;
+            mYDot = builder.mYDot;
+            mYAccel = builder.mYAccel;
+            mZ = builder.mZ;
+            mZDot = builder.mZDot;
+            mZAccel = builder.mZAccel;
+        }
+
+        /** Returns the X position in kilometers. */
+        @FloatRange(from = -2.7e4f, to = 2.7e4f)
+        public double getX() {
+            return mX;
+        }
+
+        /** Returns the X velocity in kilometers per second. */
+        @FloatRange(from = -4.3f, to = 4.3f)
+        public double getXDot() {
+            return mXDot;
+        }
+
+        /** Returns the X acceleration in kilometers per second squared. */
+        @FloatRange(from = -6.2e-9f, to = 6.2e-9f)
+        public double getXAccel() {
+            return mXAccel;
+        }
+
+        /** Returns the Y position in kilometers. */
+        @FloatRange(from = -2.7e4f, to = 2.7e4f)
+        public double getY() {
+            return mY;
+        }
+
+        /** Returns the Y velocity in kilometers per second. */
+        @FloatRange(from = -4.3f, to = 4.3f)
+        public double getYDot() {
+            return mYDot;
+        }
+
+        /** Returns the Y acceleration in kilometers per second squared. */
+        @FloatRange(from = -6.2e-9f, to = 6.2e-9f)
+        public double getYAccel() {
+            return mYAccel;
+        }
+
+        /** Returns the Z position in kilometers. */
+        @FloatRange(from = -2.7e4f, to = 2.7e4f)
+        public double getZ() {
+            return mZ;
+        }
+
+        /** Returns the Z velocity in kilometers per second. */
+        @FloatRange(from = -4.3f, to = 4.3f)
+        public double getZDot() {
+            return mZDot;
+        }
+
+        /** Returns the Z acceleration in kilometers per second squared. */
+        @FloatRange(from = -6.2e-9f, to = 6.2e-9f)
+        public double getZAccel() {
+            return mZAccel;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel dest, int flags) {
+            dest.writeDouble(mX);
+            dest.writeDouble(mXDot);
+            dest.writeDouble(mXAccel);
+            dest.writeDouble(mY);
+            dest.writeDouble(mYDot);
+            dest.writeDouble(mYAccel);
+            dest.writeDouble(mZ);
+            dest.writeDouble(mZDot);
+            dest.writeDouble(mZAccel);
+        }
+
+        public static final @NonNull Parcelable.Creator<GlonassSatelliteOrbitModel> CREATOR =
+                new Parcelable.Creator<GlonassSatelliteOrbitModel>() {
+                    @Override
+                    public GlonassSatelliteOrbitModel createFromParcel(@NonNull Parcel source) {
+                        return new GlonassSatelliteOrbitModel.Builder()
+                                .setX(source.readDouble())
+                                .setXDot(source.readDouble())
+                                .setXAccel(source.readDouble())
+                                .setY(source.readDouble())
+                                .setYDot(source.readDouble())
+                                .setYAccel(source.readDouble())
+                                .setZ(source.readDouble())
+                                .setZDot(source.readDouble())
+                                .setZAccel(source.readDouble())
+                                .build();
+                    }
+
+                    @Override
+                    public GlonassSatelliteOrbitModel[] newArray(int size) {
+                        return new GlonassSatelliteOrbitModel[size];
+                    }
+                };
+
+        @Override
+        @NonNull
+        public String toString() {
+            StringBuilder builder = new StringBuilder("GlonassSatelliteOrbitModel[");
+            builder.append("x = ").append(mX);
+            builder.append(", xDot = ").append(mXDot);
+            builder.append(", xAccel = ").append(mXAccel);
+            builder.append(", y = ").append(mY);
+            builder.append(", yDot = ").append(mYDot);
+            builder.append(", yAccel = ").append(mYAccel);
+            builder.append(", z = ").append(mZ);
+            builder.append(", zDot = ").append(mZDot);
+            builder.append(", zAccel = ").append(mZAccel);
+            builder.append("]");
+            return builder.toString();
+        }
+
+        /** Builder for {@link GlonassSatelliteOrbitModel}. */
+        public static final class Builder {
+            private double mX;
+            private double mXDot;
+            private double mXAccel;
+            private double mY;
+            private double mYDot;
+            private double mYAccel;
+            private double mZ;
+            private double mZDot;
+            private double mZAccel;
+
+            /** Sets the X position in kilometers. */
+            @NonNull
+            public Builder setX(@FloatRange(from = -2.7e4f, to = 2.7e4f) double x) {
+                mX = x;
+                return this;
+            }
+
+            /** Sets the X velocity in kilometers per second. */
+            @NonNull
+            public Builder setXDot(@FloatRange(from = -4.3f, to = 4.3f) double xDot) {
+                mXDot = xDot;
+                return this;
+            }
+
+            /** Sets the X acceleration in kilometers per second squared. */
+            @NonNull
+            public Builder setXAccel(@FloatRange(from = -6.2e-9f, to = 6.2e-9f) double xAccel) {
+                mXAccel = xAccel;
+                return this;
+            }
+
+            /** Sets the Y position in kilometers. */
+            @NonNull
+            public Builder setY(@FloatRange(from = -2.7e4f, to = 2.7e4f) double y) {
+                mY = y;
+                return this;
+            }
+
+            /** Sets the Y velocity in kilometers per second. */
+            @NonNull
+            public Builder setYDot(@FloatRange(from = -4.3f, to = 4.3f) double yDot) {
+                mYDot = yDot;
+                return this;
+            }
+
+            /** Sets the Y acceleration in kilometers per second squared. */
+            @NonNull
+            public Builder setYAccel(@FloatRange(from = -6.2e-9f, to = 6.2e-9f) double yAccel) {
+                mYAccel = yAccel;
+                return this;
+            }
+
+            /** Sets the Z position in kilometers. */
+            @NonNull
+            public Builder setZ(@FloatRange(from = -2.7e4f, to = 2.7e4f) double z) {
+                mZ = z;
+                return this;
+            }
+
+            /** Sets the Z velocity in kilometers per second. */
+            @NonNull
+            public Builder setZDot(@FloatRange(from = -4.3f, to = 4.3f) double zDot) {
+                mZDot = zDot;
+                return this;
+            }
+
+            /** Sets the Z acceleration in kilometers per second squared. */
+            @NonNull
+            public Builder setZAccel(@FloatRange(from = -6.2e-9f, to = 6.2e-9f) double zAccel) {
+                mZAccel = zAccel;
+                return this;
+            }
+
+            /** Builds a {@link GlonassSatelliteOrbitModel}. */
+            @NonNull
+            public GlonassSatelliteOrbitModel build() {
+                return new GlonassSatelliteOrbitModel(this);
+            }
+        }
+    }
+}
diff --git a/location/java/android/location/GnssAlmanac.java b/location/java/android/location/GnssAlmanac.java
new file mode 100644
index 0000000..6466e45a
--- /dev/null
+++ b/location/java/android/location/GnssAlmanac.java
@@ -0,0 +1,619 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class contains almanac parameters for GPS, QZSS, Galileo, Beidou.
+ *
+ * <p>For Beidou, this is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.15.
+ *
+ * <p>For GPS, this is defined in IS-GPS-200 section 20.3.3.5.1.2.
+ *
+ * <p>For QZSS, this is defined in IS-QZSS-PNT section 4.1.2.6.
+ *
+ * <p>For Galileo, this is defined in Galileo-OS-SIS-ICD-v2.1 section 5.1.10.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GnssAlmanac implements Parcelable {
+    /**
+     * Almanac issue date in milliseconds (UTC).
+     *
+     * <p>This is unused for GPS/QZSS/Baidou.
+     */
+    private final long mIssueDateMillis;
+
+    /**
+     * Almanac issue of data.
+     *
+     * <p>This is unused for GPS/QZSS/Baidou.
+     */
+    private final int mIod;
+
+    /**
+     * Almanac reference week number.
+     *
+     * <p>For GPS and QZSS, this is GPS week number (modulo 1024).
+     *
+     * <p>For Beidou, this is Baidou week number (modulo 8192).
+     *
+     * <p>For Galileo, this is modulo 4 representation of the Galileo week number.
+     */
+    private final int mWeekNumber;
+
+    /** Almanac reference time in seconds. */
+    private final int mToaSeconds;
+
+    /** The list of GnssSatelliteAlmanacs. */
+    @NonNull private final List<GnssSatelliteAlmanac> mGnssSatelliteAlmanacs;
+
+    private GnssAlmanac(Builder builder) {
+        Preconditions.checkArgument(builder.mIssueDateMillis >= 0);
+        Preconditions.checkArgument(builder.mIod >= 0);
+        Preconditions.checkArgument(builder.mWeekNumber >= 0);
+        Preconditions.checkArgumentInRange(builder.mToaSeconds, 0, 604800, "ToaSeconds");
+        Preconditions.checkNotNull(
+                builder.mGnssSatelliteAlmanacs, "GnssSatelliteAlmanacs cannot be null");
+        mIssueDateMillis = builder.mIssueDateMillis;
+        mIod = builder.mIod;
+        mWeekNumber = builder.mWeekNumber;
+        mToaSeconds = builder.mToaSeconds;
+        mGnssSatelliteAlmanacs =
+                Collections.unmodifiableList(new ArrayList<>(builder.mGnssSatelliteAlmanacs));
+    }
+
+    /** Returns the almanac issue date in milliseconds (UTC). */
+    @IntRange(from = 0)
+    public long getIssueDateMillis() {
+        return mIssueDateMillis;
+    }
+
+    /** Returns the almanac issue of data. */
+    @IntRange(from = 0)
+    public int getIod() {
+        return mIod;
+    }
+
+    /**
+     * Returns the almanac reference week number.
+     *
+     * <p>For GPS and QZSS, this is GPS week number (modulo 1024).
+     *
+     * <p>For Beidou, this is Baidou week number (modulo 8192).
+     *
+     * <p>For Galileo, this is modulo 4 representation of the Galileo week number.
+     */
+    @IntRange(from = 0)
+    public int getWeekNumber() {
+        return mWeekNumber;
+    }
+
+    /** Returns the almanac reference time in seconds. */
+    @IntRange(from = 0, to = 604800)
+    public int getToaSeconds() {
+        return mToaSeconds;
+    }
+
+    /** Returns the list of GnssSatelliteAlmanacs. */
+    @NonNull
+    public List<GnssSatelliteAlmanac> getGnssSatelliteAlmanacs() {
+        return mGnssSatelliteAlmanacs;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeLong(mIssueDateMillis);
+        dest.writeInt(mIod);
+        dest.writeInt(mWeekNumber);
+        dest.writeInt(mToaSeconds);
+        dest.writeTypedList(mGnssSatelliteAlmanacs);
+    }
+
+    public static final @NonNull Creator<GnssAlmanac> CREATOR =
+            new Creator<GnssAlmanac>() {
+                @Override
+                public GnssAlmanac createFromParcel(Parcel in) {
+                    GnssAlmanac.Builder gnssAlmanac = new GnssAlmanac.Builder();
+                    gnssAlmanac.setIssueDateMillis(in.readLong());
+                    gnssAlmanac.setIod(in.readInt());
+                    gnssAlmanac.setWeekNumber(in.readInt());
+                    gnssAlmanac.setToaSeconds(in.readInt());
+                    List<GnssSatelliteAlmanac> satelliteAlmanacs = new ArrayList<>();
+                    in.readTypedList(satelliteAlmanacs, GnssSatelliteAlmanac.CREATOR);
+                    gnssAlmanac.setGnssSatelliteAlmanacs(satelliteAlmanacs);
+                    return gnssAlmanac.build();
+                }
+
+                @Override
+                public GnssAlmanac[] newArray(int size) {
+                    return new GnssAlmanac[size];
+                }
+            };
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder("GnssAlmanac[");
+        builder.append("issueDateMillis=").append(mIssueDateMillis);
+        builder.append(", iod=").append(mIod);
+        builder.append(", weekNumber=").append(mWeekNumber);
+        builder.append(", toaSeconds=").append(mToaSeconds);
+        builder.append(", satelliteAlmanacs=").append(mGnssSatelliteAlmanacs);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /** Builder for {@link GnssAlmanac}. */
+    public static final class Builder {
+        private long mIssueDateMillis;
+        private int mIod;
+        private int mWeekNumber;
+        private int mToaSeconds;
+        private List<GnssSatelliteAlmanac> mGnssSatelliteAlmanacs;
+
+        /** Sets the almanac issue date in milliseconds (UTC). */
+        @NonNull
+        public Builder setIssueDateMillis(@IntRange(from = 0) long issueDateMillis) {
+            mIssueDateMillis = issueDateMillis;
+            return this;
+        }
+
+        /** Sets the almanac issue of data. */
+        @NonNull
+        public Builder setIod(@IntRange(from = 0) int iod) {
+            mIod = iod;
+            return this;
+        }
+
+        /**
+         * Sets the almanac reference week number.
+         *
+         * <p>For GPS and QZSS, this is GPS week number (modulo 1024).
+         *
+         * <p>For Beidou, this is Baidou week number (modulo 8192).
+         *
+         * <p>For Galileo, this is modulo 4 representation of the Galileo week number.
+         */
+        @NonNull
+        public Builder setWeekNumber(@IntRange(from = 0) int weekNumber) {
+            mWeekNumber = weekNumber;
+            return this;
+        }
+
+        /** Sets the almanac reference time in seconds. */
+        @NonNull
+        public Builder setToaSeconds(@IntRange(from = 0, to = 604800) int toaSeconds) {
+            mToaSeconds = toaSeconds;
+            return this;
+        }
+
+        /** Sets the list of GnssSatelliteAlmanacs. */
+        @NonNull
+        public Builder setGnssSatelliteAlmanacs(
+                @NonNull List<GnssSatelliteAlmanac> gnssSatelliteAlmanacs) {
+            mGnssSatelliteAlmanacs = gnssSatelliteAlmanacs;
+            return this;
+        }
+
+        /** Builds a {@link GnssAlmanac} instance as specified by this builder. */
+        @NonNull
+        public GnssAlmanac build() {
+            return new GnssAlmanac(this);
+        }
+    }
+
+    /**
+     * A class contains almanac parameters for GPS, QZSS, Galileo, Beidou.
+     *
+     * <p>For Beidou, this is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.15.
+     *
+     * <p>For GPS, this is defined in IS-GPS-200 section 20.3.3.5.1.2.
+     *
+     * <p>For QZSS, this is defined in IS-QZSS-PNT section 4.1.2.6.
+     *
+     * <p>For Galileo, this is defined in Galileo-OS-SIS-ICD-v2.1 section 5.1.10.
+     */
+    public static final class GnssSatelliteAlmanac implements Parcelable {
+        /** The PRN number of the GNSS satellite. */
+        private final int mSvid;
+
+        /**
+         * Satellite health information.
+         *
+         * <p>For GPS, this is satellite subframe 4 and 5, page 25 6-bit health code as defined in
+         * IS-GPS-200 Table 20-VIII expressed in integer form.
+         *
+         * <p>For QZSS, this is the 5-bit health code as defined in IS-QZSS-PNT, Table 4.1.2-5-2
+         * expressed in integer form.
+         *
+         * <p>For Beidou, this is 1-bit health information. (0=healthy, 1=unhealthy).
+         *
+         * <p>For Galileo, this is 6-bit health, bit 0 and 1 is for E5a, bit 2 and 3 is for E5b, bit
+         * 4 and 5 is for E1b.
+         */
+        private final int mSvHealth;
+
+        /** Eccentricity. */
+        private final double mEccentricity;
+
+        /**
+         * Inclination in semi-circles.
+         *
+         * <p>For GPS and Galileo, this is the difference between the inclination angle at reference
+         * time and the nominal inclination in semi-circles.
+         *
+         * <p>For Beidou and QZSS, this is the inclination angle at reference time in semi-circles.
+         */
+        private final double mInclination;
+
+        /** Argument of perigee in semi-circles. */
+        private final double mOmega;
+
+        /** Longitude of ascending node of orbital plane at weekly epoch in semi-circles. */
+        private final double mOmega0;
+
+        /** Rate of right ascension in semi-circles per second. */
+        private final double mOmegaDot;
+
+        /**
+         * Square root of semi-major axis in square root of meters.
+         *
+         * <p>For Galileo, this is the difference with respect to the square root of the nominal
+         * semi-major axis in square root of meters.
+         */
+        private final double mRootA;
+
+        /** Mean anomaly at reference time in semi-circles. */
+        private final double mM0;
+
+        /** Satellite clock time bias correction coefficient in seconds. */
+        private final double mAf0;
+
+        /** Satellite clock time drift correction coefficient in seconds per second. */
+        private final double mAf1;
+
+        private GnssSatelliteAlmanac(Builder builder) {
+            Preconditions.checkArgument(builder.mSvid > 0);
+            Preconditions.checkArgument(builder.mSvHealth >= 0);
+            Preconditions.checkArgument(builder.mEccentricity >= 0.0f);
+            Preconditions.checkArgumentInRange(builder.mInclination, -1.0f, 1.0f, "Inclination");
+            Preconditions.checkArgumentInRange(builder.mOmega, -1.0f, 1.0f, "Omega");
+            Preconditions.checkArgumentInRange(builder.mOmega0, -1.0f, 1.0f, "Omega0");
+            Preconditions.checkArgumentInRange(builder.mOmegaDot, -1.0f, 1.0f, "OmegaDot");
+            Preconditions.checkArgumentInRange(builder.mRootA, 0.0f, 8192.0f, "RootA");
+            Preconditions.checkArgumentInRange(builder.mM0, -1.0f, 1.0f, "M0");
+            Preconditions.checkArgumentInRange(builder.mAf0, -0.0625f, 0.0625f, "Af0");
+            Preconditions.checkArgumentInRange(builder.mAf1, -1.5e-8f, 1.5e-8f, "Af1");
+            mSvid = builder.mSvid;
+            mSvHealth = builder.mSvHealth;
+            mEccentricity = builder.mEccentricity;
+            mInclination = builder.mInclination;
+            mOmega = builder.mOmega;
+            mOmega0 = builder.mOmega0;
+            mOmegaDot = builder.mOmegaDot;
+            mRootA = builder.mRootA;
+            mM0 = builder.mM0;
+            mAf0 = builder.mAf0;
+            mAf1 = builder.mAf1;
+        }
+
+        /** Returns the PRN number of the GNSS satellite. */
+        @IntRange(from = 1)
+        public int getSvid() {
+            return mSvid;
+        }
+
+        /**
+         * Returns the satellite health information.
+         *
+         * <p>For GPS, this is satellite subframe 4 and 5, page 25 6-bit health code as defined in
+         * IS-GPS-200 Table 20-VIII expressed in integer form.
+         *
+         * <p>For QZSS, this is the 5-bit health code as defined in IS-QZSS-PNT, Table 4.1.2-5-2
+         * expressed in integer form.
+         *
+         * <p>For Beidou, this is 1-bit health information. (0=healthy, 1=unhealthy).
+         *
+         * <p>For Galileo, this is 6-bit health, bit 0 and 1 is for E5a, bit 2 and 3 is for E5b,
+         * bit 4 and 5 is for E1b.
+         */
+        @IntRange(from = 0)
+        public int getSvHealth() {
+            return mSvHealth;
+        }
+
+        /** Returns the eccentricity. */
+        @FloatRange(from = 0.0f)
+        public double getEccentricity() {
+            return mEccentricity;
+        }
+
+        /**
+         * Returns the inclination in semi-circles.
+         *
+         * <p>For GPS and Galileo, this is the difference between the inclination angle at reference
+         * time and the nominal inclination in semi-circles.
+         *
+         * <p>For Beidou and QZSS, this is the inclination angle at reference time in semi-circles.
+         */
+        @FloatRange(from = -1.0f, to = 1.0f)
+        public double getInclination() {
+            return mInclination;
+        }
+
+        /** Returns the argument of perigee in semi-circles. */
+        @FloatRange(from = -1.0f, to = 1.0f)
+        public double getOmega() {
+            return mOmega;
+        }
+
+        /**
+         * Returns the longitude of ascending node of orbital plane at weekly epoch in semi-circles.
+         */
+        @FloatRange(from = -1.0f, to = 1.0f)
+        public double getOmega0() {
+            return mOmega0;
+        }
+
+        /** Returns the rate of right ascension in semi-circles per second. */
+        @FloatRange(from = -1.0f, to = 1.0f)
+        public double getOmegaDot() {
+            return mOmegaDot;
+        }
+
+        /**
+         * Returns the square root of semi-major axis in square root of meters.
+         *
+         * <p>For Galileo, this is the difference with respect to the square root of the nominal
+         * semi-major axis in square root of meters.
+         */
+        @FloatRange(from = 0.0f, to = 8192.0f)
+        public double getRootA() {
+            return mRootA;
+        }
+
+        /** Returns the mean anomaly at reference time in semi-circles. */
+        @FloatRange(from = -1.0f, to = 1.0f)
+        public double getM0() {
+            return mM0;
+        }
+
+        /** Returns the satellite clock time bias correction coefficient in seconds. */
+        @FloatRange(from = -0.0625f, to = 0.0625f)
+        public double getAf0() {
+            return mAf0;
+        }
+
+        /** Returns the satellite clock time drift correction coefficient in seconds per second. */
+        @FloatRange(from = -1.5e-8f, to = 1.5e-8f)
+        public double getAf1() {
+            return mAf1;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel dest, int flags) {
+            dest.writeInt(mSvid);
+            dest.writeInt(mSvHealth);
+            dest.writeDouble(mEccentricity);
+            dest.writeDouble(mInclination);
+            dest.writeDouble(mOmega);
+            dest.writeDouble(mOmega0);
+            dest.writeDouble(mOmegaDot);
+            dest.writeDouble(mRootA);
+            dest.writeDouble(mM0);
+            dest.writeDouble(mAf0);
+            dest.writeDouble(mAf1);
+        }
+
+        public static final @NonNull Creator<GnssSatelliteAlmanac> CREATOR =
+                new Creator<GnssSatelliteAlmanac>() {
+                    @Override
+                    public GnssSatelliteAlmanac createFromParcel(Parcel in) {
+                        return new GnssSatelliteAlmanac(
+                                new Builder()
+                                        .setSvid(in.readInt())
+                                        .setSvHealth(in.readInt())
+                                        .setEccentricity(in.readDouble())
+                                        .setInclination(in.readDouble())
+                                        .setOmega(in.readDouble())
+                                        .setOmega0(in.readDouble())
+                                        .setOmegaDot(in.readDouble())
+                                        .setRootA(in.readDouble())
+                                        .setM0(in.readDouble())
+                                        .setAf0(in.readDouble())
+                                        .setAf1(in.readDouble()));
+                    }
+
+                    @Override
+                    public GnssSatelliteAlmanac[] newArray(int size) {
+                        return new GnssSatelliteAlmanac[size];
+                    }
+                };
+
+        @Override
+        @NonNull
+        public String toString() {
+            StringBuilder builder = new StringBuilder("GnssSatelliteAlmanac[");
+            builder.append("svid = ").append(mSvid);
+            builder.append(", svHealth = ").append(mSvHealth);
+            builder.append(", eccentricity = ").append(mEccentricity);
+            builder.append(", inclination = ").append(mInclination);
+            builder.append(", omega = ").append(mOmega);
+            builder.append(", omega0 = ").append(mOmega0);
+            builder.append(", omegaDot = ").append(mOmegaDot);
+            builder.append(", rootA = ").append(mRootA);
+            builder.append(", m0 = ").append(mM0);
+            builder.append(", af0 = ").append(mAf0);
+            builder.append(", af1 = ").append(mAf1);
+            builder.append("]");
+            return builder.toString();
+        }
+
+        /** Builder for {@link GnssSatelliteAlmanac}. */
+        public static final class Builder {
+            private int mSvid;
+            private int mSvHealth;
+            private double mEccentricity;
+            private double mInclination;
+            private double mOmega;
+            private double mOmega0;
+            private double mOmegaDot;
+            private double mRootA;
+            private double mM0;
+            private double mAf0;
+            private double mAf1;
+
+            /** Sets the PRN number of the GNSS satellite. */
+            @NonNull
+            public Builder setSvid(@IntRange(from = 1) int svid) {
+                mSvid = svid;
+                return this;
+            }
+
+            /**
+             * Sets the satellite health information.
+             *
+             * <p>For GPS, this is satellite subframe 4 and 5, page 25 6-bit health code as defined
+             * in IS-GPS-200 Table 20-VIII expressed in integer form.
+             *
+             * <p>For QZSS, this is the 5-bit health code as defined in IS-QZSS-PNT, Table 4.1.2-5-2
+             * expressed in integer form.
+             *
+             * <p>For Beidou, this is 1-bit health information. (0=healthy, 1=unhealthy).
+             *
+             * <p>For Galileo, this is 6-bit health, bit 0 and 1 is for E5a,
+             * bit 2 and 3 is for E5b, bit 4 and 5 is for E1b.
+             */
+            @NonNull
+            public Builder setSvHealth(@IntRange(from = 0) int svHealth) {
+                mSvHealth = svHealth;
+                return this;
+            }
+
+            /** Sets the eccentricity. */
+            @NonNull
+            public Builder setEccentricity(@FloatRange(from = 0.0f) double eccentricity) {
+                mEccentricity = eccentricity;
+                return this;
+            }
+
+            /**
+             * Sets the inclination in semi-circles.
+             *
+             * <p>For GPS and Galileo, this is the difference between the inclination angle at
+             * reference time and the nominal inclination in semi-circles.
+             *
+             * <p>For Beidou and QZSS, this is the inclination angle at reference time in
+             * semi-circles.
+             */
+            @NonNull
+            public Builder setInclination(@FloatRange(from = -1.0f, to = 1.0f) double inclination) {
+                mInclination = inclination;
+                return this;
+            }
+
+            /** Sets the argument of perigee in semi-circles. */
+            @NonNull
+            public Builder setOmega(@FloatRange(from = -1.0f, to = 1.0f) double omega) {
+                mOmega = omega;
+                return this;
+            }
+
+            /**
+             * Sets the longitude of ascending node of orbital plane at weekly epoch in
+             * semi-circles.
+             */
+            @NonNull
+            public Builder setOmega0(@FloatRange(from = -1.0f, to = 1.0f) double omega0) {
+                mOmega0 = omega0;
+                return this;
+            }
+
+            /** Sets the rate of right ascension in semi-circles per second. */
+            @NonNull
+            public Builder setOmegaDot(@FloatRange(from = -1.0f, to = 1.0f) double omegaDot) {
+                mOmegaDot = omegaDot;
+                return this;
+            }
+
+            /**
+             * Sets the square root of semi-major axis in square root of meters.
+             *
+             * <p>For Galileo, this is the difference with respect to the square root of the nominal
+             * semi-major axis in square root of meters.
+             */
+            @NonNull
+            public Builder setRootA(@FloatRange(from = 0.0f, to = 8192.0f) double rootA) {
+                mRootA = rootA;
+                return this;
+            }
+
+            /** Sets the mean anomaly at reference time in semi-circles. */
+            @NonNull
+            public Builder setM0(@FloatRange(from = -1.0f, to = 1.0f) double m0) {
+                mM0 = m0;
+                return this;
+            }
+
+            /** Sets the satellite clock time bias correction coefficient in seconds. */
+            @NonNull
+            public Builder setAf0(@FloatRange(from = -0.0625f, to = 0.0625f) double af0) {
+                mAf0 = af0;
+                return this;
+            }
+
+            /** Sets the satellite clock time drift correction coefficient in seconds per second. */
+            @NonNull
+            public Builder setAf1(@FloatRange(from = -1.5e-8f, to = 1.5e-8f) double af1) {
+                mAf1 = af1;
+                return this;
+            }
+
+            /** Builds a {@link GnssSatelliteAlmanac} instance as specified by this builder. */
+            @NonNull
+            public GnssSatelliteAlmanac build() {
+                return new GnssSatelliteAlmanac(this);
+            }
+        }
+    }
+}
diff --git a/location/java/android/location/GnssAssistance.aidl b/location/java/android/location/GnssAssistance.aidl
new file mode 100644
index 0000000..2745683
--- /dev/null
+++ b/location/java/android/location/GnssAssistance.aidl
@@ -0,0 +1,18 @@
+/*
+ * 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.location;
+
+parcelable GnssAssistance;
\ No newline at end of file
diff --git a/location/java/android/location/GnssAssistance.java b/location/java/android/location/GnssAssistance.java
new file mode 100644
index 0000000..e941122
--- /dev/null
+++ b/location/java/android/location/GnssAssistance.java
@@ -0,0 +1,310 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class contains GNSS assistance.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GnssAssistance implements Parcelable {
+
+    /** GPS assistance. */
+    @Nullable private final GpsAssistance mGpsAssistance;
+
+    /** Glonass assistance. */
+    @Nullable private final GlonassAssistance mGlonassAssistance;
+
+    /** Galileo assistance. */
+    @Nullable private final GalileoAssistance mGalileoAssistance;
+
+    /** Beidou assistance. */
+    @Nullable private final BeidouAssistance mBeidouAssistance;
+
+    /** QZSS assistance. */
+    @Nullable private final QzssAssistance mQzssAssistance;
+
+    private GnssAssistance(Builder builder) {
+        mGpsAssistance = builder.mGpsAssistance;
+        mGlonassAssistance = builder.mGlonassAssistance;
+        mGalileoAssistance = builder.mGalileoAssistance;
+        mBeidouAssistance = builder.mBeidouAssistance;
+        mQzssAssistance = builder.mQzssAssistance;
+    }
+
+    /** Returns the GPS assistance. */
+    @Nullable
+    public GpsAssistance getGpsAssistance() {
+        return mGpsAssistance;
+    }
+
+    /** Returns the Glonass assistance. */
+    @Nullable
+    public GlonassAssistance getGlonassAssistance() {
+        return mGlonassAssistance;
+    }
+
+    /** Returns the Galileo assistance. */
+    @Nullable
+    public GalileoAssistance getGalileoAssistance() {
+        return mGalileoAssistance;
+    }
+
+    /** Returns the Beidou assistance. */
+    @Nullable
+    public BeidouAssistance getBeidouAssistance() {
+        return mBeidouAssistance;
+    }
+
+    /** Returns the Qzss assistance. */
+    @Nullable
+    public QzssAssistance getQzssAssistance() {
+        return mQzssAssistance;
+    }
+
+    public static final @NonNull Creator<GnssAssistance> CREATOR =
+            new Creator<GnssAssistance>() {
+                @Override
+                @NonNull
+                public GnssAssistance createFromParcel(Parcel in) {
+                    return new GnssAssistance.Builder()
+                            .setGpsAssistance(in.readTypedObject(GpsAssistance.CREATOR))
+                            .setGlonassAssistance(in.readTypedObject(GlonassAssistance.CREATOR))
+                            .setGalileoAssistance(in.readTypedObject(GalileoAssistance.CREATOR))
+                            .setBeidouAssistance(in.readTypedObject(BeidouAssistance.CREATOR))
+                            .setQzssAssistance(in.readTypedObject(QzssAssistance.CREATOR))
+                            .build();
+                }
+
+                @Override
+                public GnssAssistance[] newArray(int size) {
+                    return new GnssAssistance[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeTypedObject(mGpsAssistance, flags);
+        parcel.writeTypedObject(mGlonassAssistance, flags);
+        parcel.writeTypedObject(mGalileoAssistance, flags);
+        parcel.writeTypedObject(mBeidouAssistance, flags);
+        parcel.writeTypedObject(mQzssAssistance, flags);
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("GnssAssistance[");
+        builder.append("gpsAssistance = ").append(mGpsAssistance);
+        builder.append(", glonassAssistance = ").append(mGlonassAssistance);
+        builder.append(", galileoAssistance = ").append(mGalileoAssistance);
+        builder.append(", beidouAssistance = ").append(mBeidouAssistance);
+        builder.append(", qzssAssistance = ").append(mQzssAssistance);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /** Builder for {@link GnssAssistance}. */
+    public static final class Builder {
+        private GpsAssistance mGpsAssistance;
+        private GlonassAssistance mGlonassAssistance;
+        private GalileoAssistance mGalileoAssistance;
+        private BeidouAssistance mBeidouAssistance;
+        private QzssAssistance mQzssAssistance;
+
+        /** Sets the GPS assistance. */
+        @NonNull
+        public Builder setGpsAssistance(@Nullable GpsAssistance gpsAssistance) {
+            mGpsAssistance = gpsAssistance;
+            return this;
+        }
+
+        /** Sets the Glonass assistance. */
+        @NonNull
+        public Builder setGlonassAssistance(@Nullable GlonassAssistance glonassAssistance) {
+            mGlonassAssistance = glonassAssistance;
+            return this;
+        }
+
+        /** Sets the Galileo assistance. */
+        @NonNull
+        public Builder setGalileoAssistance(@Nullable GalileoAssistance galileoAssistance) {
+            mGalileoAssistance = galileoAssistance;
+            return this;
+        }
+
+        /** Sets the Beidou assistance. */
+        @NonNull
+        public Builder setBeidouAssistance(@Nullable BeidouAssistance beidouAssistance) {
+            mBeidouAssistance = beidouAssistance;
+            return this;
+        }
+
+        /** Sets the QZSS assistance. */
+        @NonNull
+        public Builder setQzssAssistance(@Nullable QzssAssistance qzssAssistance) {
+            mQzssAssistance = qzssAssistance;
+            return this;
+        }
+
+        /** Builds a {@link GnssAssistance} instance as specified by this builder. */
+        @NonNull
+        public GnssAssistance build() {
+            return new GnssAssistance(this);
+        }
+    }
+
+    /** A class contains GNSS corrections for satellites. */
+    public static final class GnssSatelliteCorrections implements Parcelable {
+        /**
+         * Pseudo-random or satellite ID number for the satellite, a.k.a. Space Vehicle (SV), or OSN
+         * number for Glonass.
+         *
+         * <p>The distinction is made by looking at the constellation field. Values must be in the
+         * range of:
+         *
+         * <p>- GPS: 1-32
+         *
+         * <p>- GLONASS: 1-25
+         *
+         * <p>- QZSS: 183-206
+         *
+         * <p>- Galileo: 1-36
+         *
+         * <p>- Beidou: 1-63
+         */
+        @IntRange(from = 1, to = 206)
+        int mSvid;
+
+        /** List of Ionospheric corrections */
+        @NonNull List<IonosphericCorrection> mIonosphericCorrections;
+
+        /**
+         * Creates a new {@link GnssSatelliteCorrections} instance.
+         *
+         * @param svid The Pseudo-random or satellite ID number for the satellite, a.k.a. Space
+         *     Vehicle (SV), or OSN number for Glonass.
+         *     <p>The distinction is made by looking at the constellation field. Values must be in
+         *     the range of:
+         *     <p>- GPS: 1-32
+         *     <p>- GLONASS: 1-25
+         *     <p>- QZSS: 183-206
+         *     <p>- Galileo: 1-36
+         *     <p>- Beidou: 1-63
+         * @param ionosphericCorrections The list of Ionospheric corrections.
+         */
+        public GnssSatelliteCorrections(
+                @IntRange(from = 1, to = 206) int svid,
+                @NonNull final List<IonosphericCorrection> ionosphericCorrections) {
+            // Allow SV ID beyond the range to support potential future extensibility.
+            Preconditions.checkArgument(svid >= 1);
+            Preconditions.checkNotNull(
+                    ionosphericCorrections, "IonosphericCorrections cannot be null");
+            mSvid = svid;
+            mIonosphericCorrections =
+                    Collections.unmodifiableList(new ArrayList<>(ionosphericCorrections));
+        }
+
+        /**
+         * Returns the Pseudo-random or satellite ID number for the satellite, a.k.a. Space Vehicle
+         * (SV), or OSN number for Glonass.
+         *
+         * <p>The distinction is made by looking at the constellation field. Values must be in the
+         * range of:
+         *
+         * <p>- GPS: 1-32
+         *
+         * <p>- GLONASS: 1-25
+         *
+         * <p>- QZSS: 183-206
+         *
+         * <p>- Galileo: 1-36
+         *
+         * <p>- Beidou: 1-63
+         */
+        @IntRange(from = 1, to = 206)
+        public int getSvid() {
+            return mSvid;
+        }
+
+        /** Returns the list of Ionospheric corrections. */
+        @NonNull
+        public List<IonosphericCorrection> getIonosphericCorrections() {
+            return mIonosphericCorrections;
+        }
+
+        public static final @NonNull Creator<GnssSatelliteCorrections> CREATOR =
+                new Creator<GnssSatelliteCorrections>() {
+                    @Override
+                    @NonNull
+                    public GnssSatelliteCorrections createFromParcel(Parcel in) {
+                        int svid = in.readInt();
+                        List<IonosphericCorrection> ionosphericCorrections = new ArrayList<>();
+                        in.readTypedList(ionosphericCorrections, IonosphericCorrection.CREATOR);
+                        return new GnssSatelliteCorrections(svid, ionosphericCorrections);
+                    }
+
+                    @Override
+                    public GnssSatelliteCorrections[] newArray(int size) {
+                        return new GnssSatelliteCorrections[size];
+                    }
+                };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel parcel, int flags) {
+            parcel.writeInt(mSvid);
+            parcel.writeTypedList(mIonosphericCorrections, flags);
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            StringBuilder builder = new StringBuilder("GnssSatelliteCorrections[");
+            builder.append("svid = ").append(mSvid);
+            builder.append(", ionosphericCorrections = ").append(mIonosphericCorrections);
+            builder.append("]");
+            return builder.toString();
+        }
+    }
+}
diff --git a/location/java/android/location/GnssCorrectionComponent.java b/location/java/android/location/GnssCorrectionComponent.java
new file mode 100644
index 0000000..f55dde1
--- /dev/null
+++ b/location/java/android/location/GnssCorrectionComponent.java
@@ -0,0 +1,300 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class that contains Gnss correction associated with a component (e.g. the Ionospheric error).
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GnssCorrectionComponent implements Parcelable {
+    /**
+     * Uniquely identifies the source of correction (e.g. "Klobuchar" for ionospheric corrections).
+     * Clients should not depend on the value of the source key but, rather, can compare
+     * before/after to detect changes.
+     */
+    @NonNull private final String mSourceKey;
+
+    /** The correction is only applicable during this time interval. */
+    @NonNull private final GnssInterval mValidityInterval;
+
+    /** Pseudorange correction. */
+    @NonNull private final PseudorangeCorrection mPseudorangeCorrection;
+
+    /**
+     * Creates a GnssCorrectionComponent.
+     *
+     * @param sourceKey Uniquely identifies the source of correction (e.g. "Klobuchar" for
+     *     ionospheric corrections). Clients should not depend on the value of the source key but,
+     *     rather, can compare before/after to detect changes.
+     * @param validityInterval The correction is only applicable during this time interval.
+     * @param pseudorangeCorrection Pseudorange correction.
+     */
+    public GnssCorrectionComponent(
+            @NonNull String sourceKey,
+            @NonNull GnssInterval validityInterval,
+            @NonNull PseudorangeCorrection pseudorangeCorrection) {
+        Preconditions.checkNotNull(sourceKey, "SourceKey cannot be null");
+        Preconditions.checkNotNull(validityInterval, "ValidityInterval cannot be null");
+        Preconditions.checkNotNull(pseudorangeCorrection, "PseudorangeCorrection cannot be null");
+        mSourceKey = sourceKey;
+        mValidityInterval = validityInterval;
+        mPseudorangeCorrection = pseudorangeCorrection;
+    }
+
+    /** Returns the source key of the correction. */
+    @NonNull
+    public String getSourceKey() {
+        return mSourceKey;
+    }
+
+    /** Returns the validity interval of the correction. */
+    @NonNull
+    public GnssInterval getValidityInterval() {
+        return mValidityInterval;
+    }
+
+    /** Returns the pseudorange correction. */
+    @NonNull
+    public PseudorangeCorrection getPseudorangeCorrection() {
+        return mPseudorangeCorrection;
+    }
+
+    public static final @NonNull Creator<GnssCorrectionComponent> CREATOR =
+            new Creator<GnssCorrectionComponent>() {
+                @Override
+                @NonNull
+                public GnssCorrectionComponent createFromParcel(Parcel in) {
+                    String sourceKey = in.readString8();
+                    GnssInterval validityInterval = in.readTypedObject(GnssInterval.CREATOR);
+                    PseudorangeCorrection pseudorangeCorrection =
+                            in.readTypedObject(PseudorangeCorrection.CREATOR);
+                    return new GnssCorrectionComponent(
+                            sourceKey, validityInterval, pseudorangeCorrection);
+                }
+
+                @Override
+                public GnssCorrectionComponent[] newArray(int size) {
+                    return new GnssCorrectionComponent[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString8(mSourceKey);
+        dest.writeTypedObject(mValidityInterval, flags);
+        dest.writeTypedObject(mPseudorangeCorrection, flags);
+    }
+
+    /**
+     * Time interval referenced against the GPS epoch. The start must be less than or equal to the
+     * end. When the start equals the end, the interval is empty.
+     */
+    public static final class GnssInterval implements Parcelable {
+        /**
+         * Inclusive start of the interval in milliseconds since the GPS epoch. A timestamp matching
+         * this interval will have to be the same or after the start. Required as a reference time
+         * for the initial correction value and its rate of change over time.
+         */
+        private final long mStartMillisSinceGpsEpoch;
+
+        /**
+         * Exclusive end of the interval in milliseconds since the GPS epoch. If specified, a
+         * timestamp matching this interval will have to be before the end.
+         */
+        private final long mEndMillisSinceGpsEpoch;
+
+        /**
+         * Creates a GnssInterval.
+         *
+         * @param startMillisSinceGpsEpoch Inclusive start of the interval in milliseconds since the
+         *     GPS epoch. A timestamp matching this interval will have to be the same or after the
+         *     start. Required as a reference time for the initial correction value and its rate of
+         *     change over time.
+         * @param endMillisSinceGpsEpoch Exclusive end of the interval in milliseconds since the GPS
+         *     epoch. If specified, a timestamp matching this interval will have to be before the
+         *     end.
+         */
+        public GnssInterval(
+                @IntRange(from = 0) long startMillisSinceGpsEpoch,
+                @IntRange(from = 0) long endMillisSinceGpsEpoch) {
+            Preconditions.checkArgument(startMillisSinceGpsEpoch >= 0);
+            Preconditions.checkArgument(endMillisSinceGpsEpoch >= 0);
+            mStartMillisSinceGpsEpoch = startMillisSinceGpsEpoch;
+            mEndMillisSinceGpsEpoch = endMillisSinceGpsEpoch;
+        }
+
+        /** Returns the inclusive start of the interval in milliseconds since the GPS epoch. */
+        @IntRange(from = 0)
+        public long getStartMillisSinceGpsEpoch() {
+            return mStartMillisSinceGpsEpoch;
+        }
+
+        /** Returns the exclusive end of the interval in milliseconds since the GPS epoch. */
+        @IntRange(from = 0)
+        public long getEndMillisSinceGpsEpoch() {
+            return mEndMillisSinceGpsEpoch;
+        }
+
+        public static final @NonNull Creator<GnssInterval> CREATOR =
+                new Creator<GnssInterval>() {
+                    @Override
+                    @NonNull
+                    public GnssInterval createFromParcel(Parcel in) {
+                        return new GnssInterval(in.readLong(), in.readLong());
+                    }
+
+                    @Override
+                    public GnssInterval[] newArray(int size) {
+                        return new GnssInterval[size];
+                    }
+                };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel parcel, int flags) {
+            parcel.writeLong(mStartMillisSinceGpsEpoch);
+            parcel.writeLong(mEndMillisSinceGpsEpoch);
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            StringBuilder builder = new StringBuilder("GnssInterval[");
+            builder.append("startMillisSinceGpsEpoch = ").append(mStartMillisSinceGpsEpoch);
+            builder.append(", endMillisSinceGpsEpoch = ").append(mEndMillisSinceGpsEpoch);
+            builder.append("]");
+            return builder.toString();
+        }
+    }
+
+    /** Pseudorange correction. */
+    public static final class PseudorangeCorrection implements Parcelable {
+
+        /** Correction to be added to the measured pseudorange, in meters. */
+        private final double mCorrectionMeters;
+
+        /** Uncertainty of the correction, in meters. */
+        private final double mCorrectionUncertaintyMeters;
+
+        /**
+         * Linear approximation of the change in correction over time. Intended usage is to adjust
+         * the correction using the formula: correctionMeters + correctionRateMetersPerSecond *
+         * delta_seconds Where `delta_seconds` is the number of elapsed seconds since the beginning
+         * of the correction validity interval.
+         */
+        private final double mCorrectionRateMetersPerSecond;
+
+        /**
+         * Creates a PseudorangeCorrection.
+         *
+         * @param correctionMeters Correction to be added to the measured pseudorange, in meters.
+         * @param correctionUncertaintyMeters Uncertainty of the correction, in meters.
+         * @param correctionRateMetersPerSecond Linear approximation of the change in correction
+         *     over time. Intended usage is to adjust the correction using the formula:
+         *     correctionMeters + correctionRateMetersPerSecond * delta_seconds Where
+         *     `delta_seconds` is the number of elapsed seconds since the beginning of the
+         *     correction validity interval.
+         */
+        public PseudorangeCorrection(
+                double correctionMeters,
+                double correctionUncertaintyMeters,
+                double correctionRateMetersPerSecond) {
+            Preconditions.checkArgument(correctionUncertaintyMeters >= 0);
+            mCorrectionMeters = correctionMeters;
+            mCorrectionUncertaintyMeters = correctionUncertaintyMeters;
+            mCorrectionRateMetersPerSecond = correctionRateMetersPerSecond;
+        }
+
+        /** Returns the correction to be added to the measured pseudorange, in meters. */
+        public double getCorrectionMeters() {
+            return mCorrectionMeters;
+        }
+
+        /** Returns the uncertainty of the correction, in meters. */
+        @FloatRange(from = 0.0f)
+        public double getCorrectionUncertaintyMeters() {
+            return mCorrectionUncertaintyMeters;
+        }
+
+        /** Returns the linear approximation of the change in correction over time. */
+        public double getCorrectionRateMetersPerSecond() {
+            return mCorrectionRateMetersPerSecond;
+        }
+
+        public static final @NonNull Creator<PseudorangeCorrection> CREATOR =
+                new Creator<PseudorangeCorrection>() {
+                    @Override
+                    @NonNull
+                    public PseudorangeCorrection createFromParcel(Parcel in) {
+                        return new PseudorangeCorrection(
+                                in.readDouble(), in.readDouble(), in.readDouble());
+                    }
+
+                    @Override
+                    public PseudorangeCorrection[] newArray(int size) {
+                        return new PseudorangeCorrection[size];
+                    }
+                };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel parcel, int flags) {
+            parcel.writeDouble(mCorrectionMeters);
+            parcel.writeDouble(mCorrectionUncertaintyMeters);
+            parcel.writeDouble(mCorrectionRateMetersPerSecond);
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            StringBuilder builder = new StringBuilder("PseudorangeCorrection[");
+            builder.append("correctionMeters = ").append(mCorrectionMeters);
+            builder.append(", correctionUncertaintyMeters = ").append(mCorrectionUncertaintyMeters);
+            builder.append(", correctionRateMetersPerSecond = ")
+                    .append(mCorrectionRateMetersPerSecond);
+            builder.append("]");
+            return builder.toString();
+        }
+    }
+}
diff --git a/location/java/android/location/GpsAssistance.java b/location/java/android/location/GpsAssistance.java
new file mode 100644
index 0000000..5202fc4
--- /dev/null
+++ b/location/java/android/location/GpsAssistance.java
@@ -0,0 +1,289 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.location.GnssAssistance.GnssSatelliteCorrections;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class contains GPS assistance.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GpsAssistance implements Parcelable {
+
+    /** The GPS almanac. */
+    @Nullable private final GnssAlmanac mAlmanac;
+
+    /** The Klobuchar ionospheric model. */
+    @Nullable private final KlobucharIonosphericModel mIonosphericModel;
+
+    /** The UTC model. */
+    @Nullable private final UtcModel mUtcModel;
+
+    /** The leap seconds model. */
+    @Nullable private final LeapSecondsModel mLeapSecondsModel;
+
+    /** The list of time models. */
+    @NonNull private final List<TimeModel> mTimeModels;
+
+    /** The list of GPS ephemeris. */
+    @NonNull private final List<GpsSatelliteEphemeris> mSatelliteEphemeris;
+
+    /** The list of real time integrity models. */
+    @NonNull private final List<RealTimeIntegrityModel> mRealTimeIntegrityModels;
+
+    /** The list of GPS satellite corrections. */
+    @NonNull private final List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+    private GpsAssistance(Builder builder) {
+        mAlmanac = builder.mAlmanac;
+        mIonosphericModel = builder.mIonosphericModel;
+        mUtcModel = builder.mUtcModel;
+        mLeapSecondsModel = builder.mLeapSecondsModel;
+        if (builder.mTimeModels != null) {
+            mTimeModels = Collections.unmodifiableList(new ArrayList<>(builder.mTimeModels));
+        } else {
+            mTimeModels = new ArrayList<>();
+        }
+        if (builder.mSatelliteEphemeris != null) {
+            mSatelliteEphemeris =
+                    Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteEphemeris));
+        } else {
+            mSatelliteEphemeris = new ArrayList<>();
+        }
+        if (builder.mRealTimeIntegrityModels != null) {
+            mRealTimeIntegrityModels =
+                    Collections.unmodifiableList(new ArrayList<>(builder.mRealTimeIntegrityModels));
+        } else {
+            mRealTimeIntegrityModels = new ArrayList<>();
+        }
+        if (builder.mSatelliteCorrections != null) {
+            mSatelliteCorrections =
+                    Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteCorrections));
+        } else {
+            mSatelliteCorrections = new ArrayList<>();
+        }
+    }
+
+    /** Returns the GPS almanac. */
+    @Nullable
+    public GnssAlmanac getAlmanac() {
+        return mAlmanac;
+    }
+
+    /** Returns the Klobuchar ionospheric model. */
+    @Nullable
+    public KlobucharIonosphericModel getIonosphericModel() {
+        return mIonosphericModel;
+    }
+
+    /** Returns the UTC model. */
+    @Nullable
+    public UtcModel getUtcModel() {
+        return mUtcModel;
+    }
+
+    /** Returns the leap seconds model. */
+    @Nullable
+    public LeapSecondsModel getLeapSecondsModel() {
+        return mLeapSecondsModel;
+    }
+
+    /** Returns the list of time models. */
+    @NonNull
+    public List<TimeModel> getTimeModels() {
+        return mTimeModels;
+    }
+
+    /** Returns the list of GPS ephemeris. */
+    @NonNull
+    public List<GpsSatelliteEphemeris> getSatelliteEphemeris() {
+        return mSatelliteEphemeris;
+    }
+
+    /** Returns the list of real time integrity models. */
+    @NonNull
+    public List<RealTimeIntegrityModel> getRealTimeIntegrityModels() {
+        return mRealTimeIntegrityModels;
+    }
+
+    /** Returns the list of GPS satellite corrections. */
+    @NonNull
+    public List<GnssSatelliteCorrections> getSatelliteCorrections() {
+        return mSatelliteCorrections;
+    }
+
+    public static final @NonNull Creator<GpsAssistance> CREATOR =
+            new Creator<GpsAssistance>() {
+                @Override
+                @NonNull
+                public GpsAssistance createFromParcel(Parcel in) {
+                    return new GpsAssistance.Builder()
+                            .setAlmanac(in.readTypedObject(GnssAlmanac.CREATOR))
+                            .setIonosphericModel(
+                                    in.readTypedObject(KlobucharIonosphericModel.CREATOR))
+                            .setUtcModel(in.readTypedObject(UtcModel.CREATOR))
+                            .setLeapSecondsModel(in.readTypedObject(LeapSecondsModel.CREATOR))
+                            .setTimeModels(in.createTypedArrayList(TimeModel.CREATOR))
+                            .setSatelliteEphemeris(
+                                    in.createTypedArrayList(GpsSatelliteEphemeris.CREATOR))
+                            .setRealTimeIntegrityModels(
+                                    in.createTypedArrayList(RealTimeIntegrityModel.CREATOR))
+                            .setSatelliteCorrections(
+                                    in.createTypedArrayList(GnssSatelliteCorrections.CREATOR))
+                            .build();
+                }
+
+                @Override
+                public GpsAssistance[] newArray(int size) {
+                    return new GpsAssistance[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeTypedObject(mAlmanac, flags);
+        dest.writeTypedObject(mIonosphericModel, flags);
+        dest.writeTypedObject(mUtcModel, flags);
+        dest.writeTypedObject(mLeapSecondsModel, flags);
+        dest.writeTypedList(mTimeModels);
+        dest.writeTypedList(mSatelliteEphemeris);
+        dest.writeTypedList(mRealTimeIntegrityModels);
+        dest.writeTypedList(mSatelliteCorrections);
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("GnssAssistance[");
+        builder.append("almanac = ").append(mAlmanac);
+        builder.append(", ionosphericModel = ").append(mIonosphericModel);
+        builder.append(", utcModel = ").append(mUtcModel);
+        builder.append(", leapSecondsModel = ").append(mLeapSecondsModel);
+        builder.append(", timeModels = ").append(mTimeModels);
+        builder.append(", satelliteEphemeris = ").append(mSatelliteEphemeris);
+        builder.append(", realTimeIntegrityModels = ").append(mRealTimeIntegrityModels);
+        builder.append(", satelliteCorrections = ").append(mSatelliteCorrections);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /** Builder for {@link GpsAssistance}. */
+    public static final class Builder {
+        private GnssAlmanac mAlmanac;
+        private KlobucharIonosphericModel mIonosphericModel;
+        private UtcModel mUtcModel;
+        private LeapSecondsModel mLeapSecondsModel;
+        private List<TimeModel> mTimeModels;
+        private List<GpsSatelliteEphemeris> mSatelliteEphemeris;
+        private List<RealTimeIntegrityModel> mRealTimeIntegrityModels;
+        private List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+        /** Sets the GPS almanac. */
+        @NonNull
+        public Builder setAlmanac(
+                @Nullable @SuppressLint("NullableCollection") GnssAlmanac almanac) {
+            mAlmanac = almanac;
+            return this;
+        }
+
+        /** Sets the Klobuchar ionospheric model. */
+        @NonNull
+        public Builder setIonosphericModel(
+                @Nullable @SuppressLint("NullableCollection")
+                        KlobucharIonosphericModel ionosphericModel) {
+            mIonosphericModel = ionosphericModel;
+            return this;
+        }
+
+        /** Sets the UTC model. */
+        @NonNull
+        public Builder setUtcModel(
+                @Nullable @SuppressLint("NullableCollection") UtcModel utcModel) {
+            mUtcModel = utcModel;
+            return this;
+        }
+
+        /** Sets the leap seconds model. */
+        @NonNull
+        public Builder setLeapSecondsModel(
+                @Nullable @SuppressLint("NullableCollection") LeapSecondsModel leapSecondsModel) {
+            mLeapSecondsModel = leapSecondsModel;
+            return this;
+        }
+
+        /** Sets the list of time models. */
+        @NonNull
+        public Builder setTimeModels(
+                @Nullable @SuppressLint("NullableCollection") List<TimeModel> timeModels) {
+            mTimeModels = timeModels;
+            return this;
+        }
+
+        /** Sets the list of GPS ephemeris. */
+        @NonNull
+        public Builder setSatelliteEphemeris(
+                @Nullable @SuppressLint("NullableCollection")
+                        List<GpsSatelliteEphemeris> satelliteEphemeris) {
+            mSatelliteEphemeris = satelliteEphemeris;
+            return this;
+        }
+
+        /** Sets the list of real time integrity models. */
+        @NonNull
+        public Builder setRealTimeIntegrityModels(
+                @Nullable @SuppressLint("NullableCollection")
+                        List<RealTimeIntegrityModel> realTimeIntegrityModels) {
+            mRealTimeIntegrityModels = realTimeIntegrityModels;
+            return this;
+        }
+
+        /** Sets the list of GPS satellite corrections. */
+        @NonNull
+        public Builder setSatelliteCorrections(
+                @Nullable @SuppressLint("NullableCollection")
+                        List<GnssSatelliteCorrections> satelliteCorrections) {
+            mSatelliteCorrections = satelliteCorrections;
+            return this;
+        }
+
+        /** Builds a {@link GpsAssistance} instance as specified by this builder. */
+        @NonNull
+        public GpsAssistance build() {
+            return new GpsAssistance(this);
+        }
+    }
+}
diff --git a/location/java/android/location/GpsSatelliteEphemeris.java b/location/java/android/location/GpsSatelliteEphemeris.java
new file mode 100644
index 0000000..ec6bc59
--- /dev/null
+++ b/location/java/android/location/GpsSatelliteEphemeris.java
@@ -0,0 +1,632 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * This class contains ephemeris parameters specific to GPS satellites.
+ *
+ * <p>This is defined in IS-GPS-200 section 20.3.3.3.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GpsSatelliteEphemeris implements Parcelable {
+    /** Satellite PRN */
+    private final int mPrn;
+
+    /** L2 parameters. */
+    @NonNull private final GpsL2Params mGpsL2Params;
+
+    /** Clock model. */
+    @NonNull private final GpsSatelliteClockModel mSatelliteClockModel;
+
+    /** Orbit model. */
+    @NonNull private final KeplerianOrbitModel mSatelliteOrbitModel;
+
+    /** Satellite health. */
+    @NonNull private final GpsSatelliteHealth mSatelliteHealth;
+
+    /** Ephemeris time. */
+    @NonNull private final SatelliteEphemerisTime mSatelliteEphemerisTime;
+
+    private GpsSatelliteEphemeris(Builder builder) {
+        // Allow PRN beyond the range to support potential future extensibility.
+        Preconditions.checkArgument(builder.mPrn >= 1);
+        Preconditions.checkNotNull(builder.mGpsL2Params, "GPSL2Params cannot be null");
+        Preconditions.checkNotNull(builder.mSatelliteClockModel,
+                "SatelliteClockModel cannot be null");
+        Preconditions.checkNotNull(builder.mSatelliteOrbitModel,
+                "SatelliteOrbitModel cannot be null");
+        Preconditions.checkNotNull(builder.mSatelliteHealth,
+                "SatelliteHealth cannot be null");
+        Preconditions.checkNotNull(builder.mSatelliteEphemerisTime,
+                "SatelliteEphemerisTime cannot be null");
+        mPrn = builder.mPrn;
+        mGpsL2Params = builder.mGpsL2Params;
+        mSatelliteClockModel = builder.mSatelliteClockModel;
+        mSatelliteOrbitModel = builder.mSatelliteOrbitModel;
+        mSatelliteHealth = builder.mSatelliteHealth;
+        mSatelliteEphemerisTime = builder.mSatelliteEphemerisTime;
+    }
+
+    /** Returns the PRN of the satellite. */
+    @IntRange(from = 1, to = 32)
+    public int getPrn() {
+        return mPrn;
+    }
+
+    /** Returns the L2 parameters of the satellite. */
+    @NonNull
+    public GpsL2Params getGpsL2Params() {
+        return mGpsL2Params;
+    }
+
+    /** Returns the clock model of the satellite. */
+    @NonNull
+    public GpsSatelliteClockModel getSatelliteClockModel() {
+        return mSatelliteClockModel;
+    }
+
+    /** Returns the orbit model of the satellite. */
+    @NonNull
+    public KeplerianOrbitModel getSatelliteOrbitModel() {
+        return mSatelliteOrbitModel;
+    }
+
+    /** Returns the satellite health. */
+    @NonNull
+    public GpsSatelliteHealth getSatelliteHealth() {
+        return mSatelliteHealth;
+    }
+
+    /** Returns the ephemeris time. */
+    @NonNull
+    public SatelliteEphemerisTime getSatelliteEphemerisTime() {
+        return mSatelliteEphemerisTime;
+    }
+
+    public static final @NonNull Creator<GpsSatelliteEphemeris> CREATOR =
+            new Creator<GpsSatelliteEphemeris>() {
+                @Override
+                @NonNull
+                public GpsSatelliteEphemeris createFromParcel(Parcel in) {
+                    final GpsSatelliteEphemeris.Builder gpsSatelliteEphemeris =
+                            new Builder()
+                                    .setPrn(in.readInt())
+                                    .setGpsL2Params(in.readTypedObject(GpsL2Params.CREATOR))
+                                    .setSatelliteClockModel(
+                                            in.readTypedObject(GpsSatelliteClockModel.CREATOR))
+                                    .setSatelliteOrbitModel(
+                                            in.readTypedObject(KeplerianOrbitModel.CREATOR))
+                                    .setSatelliteHealth(
+                                            in.readTypedObject(GpsSatelliteHealth.CREATOR))
+                                    .setSatelliteEphemerisTime(
+                                            in.readTypedObject(SatelliteEphemerisTime.CREATOR));
+                    return gpsSatelliteEphemeris.build();
+                }
+
+                @Override
+                public GpsSatelliteEphemeris[] newArray(int size) {
+                    return new GpsSatelliteEphemeris[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeInt(mPrn);
+        parcel.writeTypedObject(mGpsL2Params, flags);
+        parcel.writeTypedObject(mSatelliteClockModel, flags);
+        parcel.writeTypedObject(mSatelliteOrbitModel, flags);
+        parcel.writeTypedObject(mSatelliteHealth, flags);
+        parcel.writeTypedObject(mSatelliteEphemerisTime, flags);
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("GpsSatelliteEphemeris[");
+        builder.append("prn = ").append(mPrn);
+        builder.append(", gpsL2Params = ").append(mGpsL2Params);
+        builder.append(", satelliteClockModel = ").append(mSatelliteClockModel);
+        builder.append(", satelliteOrbitModel = ").append(mSatelliteOrbitModel);
+        builder.append(", satelliteHealth = ").append(mSatelliteHealth);
+        builder.append(", satelliteEphemerisTime = ").append(mSatelliteEphemerisTime);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /** Builder for {@link GpsSatelliteEphemeris} */
+    public static final class Builder {
+        private int mPrn = 0;
+        private GpsL2Params mGpsL2Params;
+        private GpsSatelliteClockModel mSatelliteClockModel;
+        private KeplerianOrbitModel mSatelliteOrbitModel;
+        private GpsSatelliteHealth mSatelliteHealth;
+        private SatelliteEphemerisTime mSatelliteEphemerisTime;
+
+        /** Sets the PRN of the satellite. */
+        @NonNull
+        public Builder setPrn(@IntRange(from = 1, to = 32) int prn) {
+            mPrn = prn;
+            return this;
+        }
+
+        /** Sets the L2 parameters of the satellite. */
+        @NonNull
+        public Builder setGpsL2Params(@NonNull GpsL2Params gpsL2Params) {
+            mGpsL2Params = gpsL2Params;
+            return this;
+        }
+
+        /** Sets the clock model of the satellite. */
+        @NonNull
+        public Builder setSatelliteClockModel(@NonNull GpsSatelliteClockModel satelliteClockModel) {
+            mSatelliteClockModel = satelliteClockModel;
+            return this;
+        }
+
+        /** Sets the orbit model of the satellite. */
+        @NonNull
+        public Builder setSatelliteOrbitModel(@NonNull KeplerianOrbitModel satelliteOrbitModel) {
+            mSatelliteOrbitModel = satelliteOrbitModel;
+            return this;
+        }
+
+        /** Sets the satellite health. */
+        @NonNull
+        public Builder setSatelliteHealth(@NonNull GpsSatelliteHealth satelliteHealth) {
+            mSatelliteHealth = satelliteHealth;
+            return this;
+        }
+
+        /** Sets the ephemeris time. */
+        @NonNull
+        public Builder setSatelliteEphemerisTime(
+                @NonNull SatelliteEphemerisTime satelliteEphemerisTime) {
+            mSatelliteEphemerisTime = satelliteEphemerisTime;
+            return this;
+        }
+
+        /** Builds a {@link GpsSatelliteEphemeris} instance as specified by this builder. */
+        @NonNull
+        public GpsSatelliteEphemeris build() {
+            return new GpsSatelliteEphemeris(this);
+        }
+    }
+
+    /**
+     * A class contains information about GPS health. The information is tied to Legacy Navigation
+     * (LNAV) data, not Civil Navigation (CNAV) data.
+     */
+    public static final class GpsSatelliteHealth implements Parcelable {
+        /**
+         * Represents "SV health" in the "BROADCAST ORBIT - 6" record of RINEX 3.05. Table A6,
+         * pp.68.
+         */
+        private final int mSvHealth;
+
+        /**
+         * Represents "SV accuracy" in meters in the "BROADCAST ORBIT - 6" record of RINEX 3.05.
+         * Table A6, pp.68.
+         */
+        private final double mSvAccur;
+
+        /**
+         * Represents the "Fit Interval" in hours in the "BROADCAST ORBIT - 7" record of RINEX 3.05.
+         * Table A6, pp.69.
+         */
+        private final double mFitInt;
+
+        /** Returns the SV health. */
+        @IntRange(from = 0, to = 63)
+        public int getSvHealth() {
+            return mSvHealth;
+        }
+
+        /** Returns the SV accuracy in meters. */
+        @FloatRange(from = 0.0f, to = 8192.0f)
+        public double getSvAccur() {
+            return mSvAccur;
+        }
+
+        /** Returns the fit interval in hours. */
+        @FloatRange(from = 0.0f)
+        public double getFitInt() {
+            return mFitInt;
+        }
+
+        private GpsSatelliteHealth(Builder builder) {
+            // Allow SV health beyond the range to support potential future extensibility.
+            Preconditions.checkArgument(builder.mSvHealth >= 0);
+            Preconditions.checkArgumentInRange(builder.mSvAccur, 0.0f, 8192.0f, "SvAccur");
+            Preconditions.checkArgument(builder.mFitInt >= 0.0f);
+            mSvHealth = builder.mSvHealth;
+            mSvAccur = builder.mSvAccur;
+            mFitInt = builder.mFitInt;
+        }
+
+        public static final @NonNull Creator<GpsSatelliteHealth> CREATOR =
+                new Creator<GpsSatelliteHealth>() {
+                    @Override
+                    @NonNull
+                    public GpsSatelliteHealth createFromParcel(Parcel in) {
+                        final GpsSatelliteHealth.Builder gpsSatelliteHealth =
+                                new Builder()
+                                        .setSvHealth(in.readInt())
+                                        .setSvAccur(in.readDouble())
+                                        .setFitInt(in.readDouble());
+                        return gpsSatelliteHealth.build();
+                    }
+
+                    @Override
+                    public GpsSatelliteHealth[] newArray(int size) {
+                        return new GpsSatelliteHealth[size];
+                    }
+                };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel parcel, int flags) {
+            parcel.writeInt(mSvHealth);
+            parcel.writeDouble(mSvAccur);
+            parcel.writeDouble(mFitInt);
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            StringBuilder builder = new StringBuilder("GpsSatelliteHealth[");
+            builder.append("svHealth = ").append(mSvHealth);
+            builder.append(", svAccur = ").append(mSvAccur);
+            builder.append(", fitInt = ").append(mFitInt);
+            builder.append("]");
+            return builder.toString();
+        }
+
+        /** Builder for {@link GpsSatelliteHealth}. */
+        public static final class Builder {
+            private int mSvHealth;
+            private double mSvAccur;
+            private double mFitInt;
+
+            /** Sets the SV health. */
+            @NonNull
+            public Builder setSvHealth(@IntRange(from = 0, to = 63) int svHealth) {
+                mSvHealth = svHealth;
+                return this;
+            }
+
+            /** Sets the SV accuracy in meters. */
+            @NonNull
+            public Builder setSvAccur(@FloatRange(from = 0.0f, to = 8192.0f) double svAccur) {
+                mSvAccur = svAccur;
+                return this;
+            }
+
+            /** Sets the fit interval in hours. */
+            @NonNull
+            public Builder setFitInt(@FloatRange(from = 0.0f) double fitInt) {
+                mFitInt = fitInt;
+                return this;
+            }
+
+            /** Builds a {@link GpsSatelliteHealth} instance as specified by this builder. */
+            @NonNull
+            public GpsSatelliteHealth build() {
+                return new GpsSatelliteHealth(this);
+            }
+        }
+    }
+
+    /** A class contains L2 parameters specific to GPS satellites. */
+    public static final class GpsL2Params implements Parcelable {
+        /** Code(s) on L2 Channel. */
+        private final int mL2Code;
+
+        /** Data Flag for L2 P-Code. */
+        private final int mL2Flag;
+
+        /** Returns the code(s) on L2 channel. */
+        @IntRange(from = 0, to = 3)
+        public int getL2Code() {
+            return mL2Code;
+        }
+
+        /** Returns the data flag for L2 P-code. */
+        @IntRange(from = 0, to = 1)
+        public int getL2Flag() {
+            return mL2Flag;
+        }
+
+        private GpsL2Params(Builder builder) {
+            Preconditions.checkArgumentInRange(builder.mL2Code, 0, 3, "L2 code");
+            Preconditions.checkArgumentInRange(builder.mL2Flag, 0, 1, "L2 flag");
+            mL2Code = builder.mL2Code;
+            mL2Flag = builder.mL2Flag;
+        }
+
+        public static final @NonNull Creator<GpsL2Params> CREATOR =
+                new Creator<GpsL2Params>() {
+                    @Override
+                    @NonNull
+                    public GpsL2Params createFromParcel(Parcel in) {
+                        final GpsL2Params.Builder gpsL2Params =
+                                new Builder().setL2Code(in.readInt()).setL2Flag(in.readInt());
+                        return gpsL2Params.build();
+                    }
+
+                    @Override
+                    public GpsL2Params[] newArray(int size) {
+                        return new GpsL2Params[size];
+                    }
+                };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel parcel, int flags) {
+            parcel.writeInt(mL2Code);
+            parcel.writeInt(mL2Flag);
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            StringBuilder builder = new StringBuilder("GpsL2Params[");
+            builder.append("l2Code = ").append(mL2Code);
+            builder.append(", l2Flag = ").append(mL2Flag);
+            builder.append("]");
+            return builder.toString();
+        }
+
+        /** Builder for {@link GpsL2Params}. */
+        public static final class Builder {
+            private int mL2Code = 0;
+            private int mL2Flag = 0;
+
+            /** Sets the code(s) on L2 channel. */
+            @NonNull
+            public Builder setL2Code(@IntRange(from = 0, to = 3) int l2Code) {
+                mL2Code = l2Code;
+                return this;
+            }
+
+            /** Sets the data flag for L2 P-code. */
+            @NonNull
+            public Builder setL2Flag(@IntRange(from = 0, to = 1) int l2Flag) {
+                mL2Flag = l2Flag;
+                return this;
+            }
+
+            /** Builds a {@link GpsL2Params} instance as specified by this builder. */
+            @NonNull
+            public GpsL2Params build() {
+                return new GpsL2Params(this);
+            }
+        }
+    }
+
+    /** A class contains the set of parameters needed for GPS satellite clock correction. */
+    public static final class GpsSatelliteClockModel implements Parcelable {
+        /**
+         * Time of the clock in seconds since GPS epoch.
+         *
+         * <p>Corresponds to the 'Epoch' field within the 'SV/EPOCH/SV CLK' record of GPS
+         * navigation message in RINEX 3.05 Table A6.
+         */
+        private final long mTimeOfClockSeconds;
+
+        /** SV clock bias in seconds. */
+        private final double mAf0;
+
+        /** SV clock drift in seconds per second. */
+        private final double mAf1;
+
+        /** Clock drift rate in seconds per second squared. */
+        private final double mAf2;
+
+        /** Group delay differential in seconds. */
+        private final double mTgd;
+
+        /** Issue of data, clock. */
+        private final int mIodc;
+
+        private GpsSatelliteClockModel(Builder builder) {
+            Preconditions.checkArgument(builder.mTimeOfClockSeconds >= 0);
+            Preconditions.checkArgumentInRange(builder.mAf0, -9.77e-3f, 9.77e-3f, "Af0");
+            Preconditions.checkArgumentInRange(builder.mAf1, -3.73e-9f, 3.73e-9f, "Af1");
+            Preconditions.checkArgumentInRange(builder.mAf2, -3.56e-15f, 3.56e-15f, "Af2");
+            Preconditions.checkArgumentInRange(builder.mTgd, -5.97e-8f, 5.97e-8f, "Tgd");
+            Preconditions.checkArgumentInRange(builder.mIodc, 0, 1023, "Iodc");
+            mTimeOfClockSeconds = builder.mTimeOfClockSeconds;
+            mAf0 = builder.mAf0;
+            mAf1 = builder.mAf1;
+            mAf2 = builder.mAf2;
+            mTgd = builder.mTgd;
+            mIodc = builder.mIodc;
+        }
+
+        /** Returns the time of the clock in seconds since GPS epoch. */
+        @IntRange(from = 0)
+        public long getTimeOfClockSeconds() {
+            return mTimeOfClockSeconds;
+        }
+
+        /** Returns the SV clock bias in seconds. */
+        @FloatRange(from = -9.77e-3f, to = 9.77e-3f)
+        public double getAf0() {
+            return mAf0;
+        }
+
+        /** Returns the SV clock drift in seconds per second. */
+        @FloatRange(from = -3.73e-9f, to = 3.73e-9f)
+        public double getAf1() {
+            return mAf1;
+        }
+
+        /** Returns the clock drift rate in seconds per second squared. */
+        @FloatRange(from = -3.56e-15f, to = 3.56e-15f)
+        public double getAf2() {
+            return mAf2;
+        }
+
+        /** Returns the group delay differential in seconds. */
+        @FloatRange(from = -5.97e-8f, to = 5.97e-8f)
+        public double getTgd() {
+            return mTgd;
+        }
+
+        /** Returns the issue of data, clock. */
+        @IntRange(from = 0, to = 1023)
+        public int getIodc() {
+            return mIodc;
+        }
+
+        public static final @NonNull Creator<GpsSatelliteClockModel> CREATOR =
+                new Creator<GpsSatelliteClockModel>() {
+                    @Override
+                    @NonNull
+                    public GpsSatelliteClockModel createFromParcel(Parcel in) {
+                        final GpsSatelliteClockModel.Builder gpsSatelliteClockModel =
+                                new Builder()
+                                        .setTimeOfClockSeconds(in.readLong())
+                                        .setAf0(in.readDouble())
+                                        .setAf1(in.readDouble())
+                                        .setAf2(in.readDouble())
+                                        .setTgd(in.readDouble())
+                                        .setIodc(in.readInt());
+                        return gpsSatelliteClockModel.build();
+                    }
+
+                    @Override
+                    public GpsSatelliteClockModel[] newArray(int size) {
+                        return new GpsSatelliteClockModel[size];
+                    }
+                };
+
+        @Override
+        public void writeToParcel(@NonNull Parcel parcel, int flags) {
+            parcel.writeLong(mTimeOfClockSeconds);
+            parcel.writeDouble(mAf0);
+            parcel.writeDouble(mAf1);
+            parcel.writeDouble(mAf2);
+            parcel.writeDouble(mTgd);
+            parcel.writeInt(mIodc);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            StringBuilder builder = new StringBuilder("GpsSatelliteClockModel[");
+            builder.append("timeOfClockSeconds = ").append(mTimeOfClockSeconds);
+            builder.append(", af0 = ").append(mAf0);
+            builder.append(", af1 = ").append(mAf1);
+            builder.append(", af2 = ").append(mAf2);
+            builder.append(", tgd = ").append(mTgd);
+            builder.append(", iodc = ").append(mIodc);
+            builder.append("]");
+            return builder.toString();
+        }
+
+        /** Builder for {@link GpsSatelliteClockModel}. */
+        public static final class Builder {
+            private long mTimeOfClockSeconds;
+            private double mAf0;
+            private double mAf1;
+            private double mAf2;
+            private double mTgd;
+            private int mIodc;
+
+            /** Sets the time of the clock in seconds since GPS epoch. */
+            @NonNull
+            public Builder setTimeOfClockSeconds(@IntRange(from = 0) long timeOfClockSeconds) {
+                mTimeOfClockSeconds = timeOfClockSeconds;
+                return this;
+            }
+
+            /** Sets the SV clock bias in seconds. */
+            @NonNull
+            public Builder setAf0(@FloatRange(from = -9.77e-3f, to = 9.77e-3f) double af0) {
+                mAf0 = af0;
+                return this;
+            }
+
+            /** Sets the SV clock drift in seconds per second. */
+            @NonNull
+            public Builder setAf1(@FloatRange(from = -3.73e-9f, to = 3.73e-9f) double af1) {
+                mAf1 = af1;
+                return this;
+            }
+
+            /** Sets the clock drift rate in seconds per second squared. */
+            @NonNull
+            public Builder setAf2(@FloatRange(from = -3.56e-15f, to = 3.56e-15f) double af2) {
+                mAf2 = af2;
+                return this;
+            }
+
+            /** Sets the group delay differential in seconds. */
+            @NonNull
+            public Builder setTgd(@FloatRange(from = -5.97e-8f, to = 5.97e-8f) double tgd) {
+                mTgd = tgd;
+                return this;
+            }
+
+            /** Sets the issue of data, clock. */
+            @NonNull
+            public Builder setIodc(@IntRange(from = 0, to = 1023) int iodc) {
+                mIodc = iodc;
+                return this;
+            }
+
+            /** Builds a {@link GpsSatelliteClockModel} instance as specified by this builder. */
+            @NonNull
+            public GpsSatelliteClockModel build() {
+                return new GpsSatelliteClockModel(this);
+            }
+        }
+    }
+}
diff --git a/location/java/android/location/IonosphericCorrection.java b/location/java/android/location/IonosphericCorrection.java
new file mode 100644
index 0000000..aafcf83
--- /dev/null
+++ b/location/java/android/location/IonosphericCorrection.java
@@ -0,0 +1,112 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains ionospheric correction.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class IonosphericCorrection implements Parcelable {
+
+    /** Carrier frequency in Hz to differentiate signals from the same satellite. e.g. GPS L1/L5 */
+    private final long mCarrierFrequencyHz;
+
+    /** Ionospheric correction. */
+    @NonNull private final GnssCorrectionComponent mIonosphericCorrection;
+
+    /**
+     * Creates a new {@link IonosphericCorrection} instance.
+     *
+     * @param carrierFrequencyHz Carrier frequency in Hz to differentiate signals from the
+     *     samesatellite. e.g. GPS L1/L5
+     * @param ionosphericCorrection Ionospheric correction.
+     */
+    public IonosphericCorrection(
+            @IntRange(from = 0) long carrierFrequencyHz,
+            @NonNull GnssCorrectionComponent ionosphericCorrection) {
+        Preconditions.checkArgument(carrierFrequencyHz > 0);
+        Preconditions.checkNotNull(ionosphericCorrection, "IonosphericCorrection cannot be null");
+        mCarrierFrequencyHz = carrierFrequencyHz;
+        mIonosphericCorrection = ionosphericCorrection;
+    }
+
+    /**
+     * Returns the carrier frequency in Hz to differentiate signals from the same satellite. e.g.
+     * GPS L1/L5
+     */
+    @IntRange(from = 0)
+    public long getCarrierFrequencyHz() {
+        return mCarrierFrequencyHz;
+    }
+
+    /** Returns the Ionospheric correction. */
+    @NonNull
+    public GnssCorrectionComponent getIonosphericCorrection() {
+        return mIonosphericCorrection;
+    }
+
+    public static final @NonNull Creator<IonosphericCorrection> CREATOR =
+            new Creator<IonosphericCorrection>() {
+                @Override
+                @NonNull
+                public IonosphericCorrection createFromParcel(Parcel in) {
+                    long carrierFrequencyHz = in.readLong();
+                    GnssCorrectionComponent ionosphericCorrection =
+                            in.readTypedObject(GnssCorrectionComponent.CREATOR);
+                    return new IonosphericCorrection(carrierFrequencyHz, ionosphericCorrection);
+                }
+
+                @Override
+                public IonosphericCorrection[] newArray(int size) {
+                    return new IonosphericCorrection[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeLong(mCarrierFrequencyHz);
+        dest.writeTypedObject(mIonosphericCorrection, flags);
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("IonosphericCorrection[");
+        builder.append("carrierFrequencyHz = ").append(mCarrierFrequencyHz);
+        builder.append(", ionosphericCorrection = ").append(mIonosphericCorrection);
+        builder.append("]");
+        return builder.toString();
+    }
+}
diff --git a/location/java/android/location/KeplerianOrbitModel.java b/location/java/android/location/KeplerianOrbitModel.java
new file mode 100644
index 0000000..a118274
--- /dev/null
+++ b/location/java/android/location/KeplerianOrbitModel.java
@@ -0,0 +1,518 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Contains Keplerian orbit model parameters for GPS/Galileo/QZSS/Beidou.
+ * <p>For GPS, this is defined in IS-GPS-200 Table 20-II.
+ * <p>For Galileo, this is defined in Galileo-OS-SIS-ICD-v2.1 section 5.1.1.
+ * <p>For QZSS, this is defined in IS-QZSS-PNT section 4.1.2.
+ * <p>For Baidou, this is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.12.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class KeplerianOrbitModel implements Parcelable {
+    /** Square root of the semi-major axis in square root of meters. */
+    private final double mRootA;
+
+    /** Eccentricity. */
+    private final double mEccentricity;
+
+    /** Inclination angle at reference time in radians. */
+    private final double mI0;
+
+    /** Rate of change of inclination angle in radians per second. */
+    private final double mIDot;
+
+    /** Argument of perigee in radians. */
+    private final double mOmega;
+
+    /** Longitude of ascending node of orbit plane at beginning of week in radians. */
+    private final double mOmega0;
+
+    /** Rate of right ascension in radians per second. */
+    private final double mOmegaDot;
+
+    /** Mean anomaly at reference time in radians. */
+    private final double mM0;
+
+    /** Mean motion difference from computed value in radians per second. */
+    private final double mDeltaN;
+
+    /** Second-order harmonic perturbations. */
+    SecondOrderHarmonicPerturbation mSecondOrderHarmonicPerturbation;
+
+    private KeplerianOrbitModel(Builder builder) {
+        Preconditions.checkArgumentInRange(builder.mRootA, 0.0f, 8192.0f, "RootA");
+        Preconditions.checkArgumentInRange(builder.mEccentricity, 0.0f, 0.5f, "Eccentricity");
+        Preconditions.checkArgumentInRange(builder.mI0, -3.15f, 3.15f, "I0");
+        Preconditions.checkArgumentInRange(builder.mIDot, -2.94e-9f, 2.94e-9f, "IDot");
+        Preconditions.checkArgumentInRange(builder.mOmega, -3.15f, 3.15f, "Omega");
+        Preconditions.checkArgumentInRange(builder.mOmega0, -3.15f, 3.15f, "Omega0");
+        Preconditions.checkArgumentInRange(builder.mOmegaDot, -3.1e-6f, 3.1e-6f, "OmegaDot");
+        Preconditions.checkArgumentInRange(builder.mM0, -3.15f, 3.15f, "M0");
+        Preconditions.checkArgumentInRange(builder.mDeltaN, -1.18e-8f, 1.18e-8f, "DeltaN");
+        mRootA = builder.mRootA;
+        mEccentricity = builder.mEccentricity;
+        mI0 = builder.mI0;
+        mIDot = builder.mIDot;
+        mOmega = builder.mOmega;
+        mOmega0 = builder.mOmega0;
+        mOmegaDot = builder.mOmegaDot;
+        mM0 = builder.mM0;
+        mDeltaN = builder.mDeltaN;
+        mSecondOrderHarmonicPerturbation = builder.mSecondOrderHarmonicPerturbation;
+    }
+
+    /** Get the square root of the semi-major axis in square root of meters. */
+    @FloatRange(from = 0.0f, to = 8192.0f)
+    public double getRootA() {
+        return mRootA;
+    }
+
+    /** Get the eccentricity. */
+    @FloatRange(from = 0.0f, to = 0.5f)
+    public double getEccentricity() {
+        return mEccentricity;
+    }
+
+    /** Get the inclination angle at reference time in radians. */
+    @FloatRange(from = -3.15f, to = 3.15f)
+    public double getI0() {
+        return mI0;
+    }
+
+    /** Get the rate of change of inclination angle in radians per second. */
+    @FloatRange(from = -2.94e-9f, to = 2.94e-9f)
+    public double getIDot() {
+        return mIDot;
+    }
+
+    /** Get the argument of perigee in radians. */
+    @FloatRange(from = -3.15f, to = 3.15f)
+    public double getOmega() {
+        return mOmega;
+    }
+
+    /** Get the longitude of ascending node of orbit plane at beginning of week in radians. */
+    @FloatRange(from = -3.15f, to = 3.15f)
+    public double getOmega0() {
+        return mOmega0;
+    }
+
+    /** Get the rate of right ascension in radians per second. */
+    @FloatRange(from = -3.1e-6f, to = 3.1e-6f)
+    public double getOmegaDot() {
+        return mOmegaDot;
+    }
+
+    /** Get the mean anomaly at reference time in radians. */
+    @FloatRange(from = -3.15f, to = 3.15f)
+    public double getM0() {
+        return mM0;
+    }
+
+    /** Get the mean motion difference from computed value in radians per second. */
+    @FloatRange(from = -1.18e-8f, to = 1.18e-8f)
+    public double getDeltaN() {
+        return mDeltaN;
+    }
+
+    /** Get the second-order harmonic perturbations. */
+    @NonNull
+    public SecondOrderHarmonicPerturbation getSecondOrderHarmonicPerturbation() {
+        return mSecondOrderHarmonicPerturbation;
+    }
+
+    public static final @NonNull Creator<KeplerianOrbitModel> CREATOR =
+            new Creator<KeplerianOrbitModel>() {
+                @Override
+                @NonNull
+                public KeplerianOrbitModel createFromParcel(Parcel in) {
+                    final KeplerianOrbitModel.Builder keplerianOrbitModel =
+                            new Builder()
+                                    .setRootA(in.readDouble())
+                                    .setEccentricity(in.readDouble())
+                                    .setI0(in.readDouble())
+                                    .setIDot(in.readDouble())
+                                    .setOmega(in.readDouble())
+                                    .setOmega0(in.readDouble())
+                                    .setOmegaDot(in.readDouble())
+                                    .setM0(in.readDouble())
+                                    .setDeltaN(in.readDouble())
+                                    .setSecondOrderHarmonicPerturbation(
+                                            in.readTypedObject(
+                                                    SecondOrderHarmonicPerturbation.CREATOR));
+                    return keplerianOrbitModel.build();
+                }
+
+                @Override
+                public KeplerianOrbitModel[] newArray(int size) {
+                    return new KeplerianOrbitModel[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeDouble(mRootA);
+        parcel.writeDouble(mEccentricity);
+        parcel.writeDouble(mI0);
+        parcel.writeDouble(mIDot);
+        parcel.writeDouble(mOmega);
+        parcel.writeDouble(mOmega0);
+        parcel.writeDouble(mOmegaDot);
+        parcel.writeDouble(mM0);
+        parcel.writeDouble(mDeltaN);
+        parcel.writeTypedObject(mSecondOrderHarmonicPerturbation, flags);
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("KeplerianOrbitModel[");
+        builder.append("rootA = ").append(mRootA);
+        builder.append(", eccentricity = ").append(mEccentricity);
+        builder.append(", i0 = ").append(mI0);
+        builder.append(", iDot = ").append(mIDot);
+        builder.append(", omega = ").append(mOmega);
+        builder.append(", omega0 = ").append(mOmega0);
+        builder.append(", omegaDot = ").append(mOmegaDot);
+        builder.append(", m0 = ").append(mM0);
+        builder.append(", deltaN = ").append(mDeltaN);
+        builder.append(", secondOrderHarmonicPerturbation = ")
+                .append(mSecondOrderHarmonicPerturbation);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /** Builder for {@link KeplerianOrbitModel} */
+    public static final class Builder {
+        private double mRootA;
+        private double mEccentricity;
+        private double mI0;
+        private double mIDot;
+        private double mOmega;
+        private double mOmega0;
+        private double mOmegaDot;
+        private double mM0;
+        private double mDeltaN;
+        private SecondOrderHarmonicPerturbation mSecondOrderHarmonicPerturbation;
+
+        /** Sets the square root of the semi-major axis in square root of meters. */
+        @NonNull
+        public Builder setRootA(@FloatRange(from = 0.0f, to = 8192.0f) double rootA) {
+            mRootA = rootA;
+            return this;
+        }
+
+        /** Sets the eccentricity. */
+        @NonNull
+        public Builder setEccentricity(@FloatRange(from = 0.0f, to = 0.5f) double eccentricity) {
+            mEccentricity = eccentricity;
+            return this;
+        }
+
+        /** Sets the inclination angle at reference time in radians. */
+        @NonNull
+        public Builder setI0(@FloatRange(from = -3.15f, to = 3.15f) double i0) {
+            mI0 = i0;
+            return this;
+        }
+
+        /** Sets the rate of change of inclination angle in radians per second. */
+        @NonNull
+        public Builder setIDot(@FloatRange(from = -2.94e-9f, to = 2.94e-9f) double iDot) {
+            mIDot = iDot;
+            return this;
+        }
+
+        /** Sets the argument of perigee in radians. */
+        @NonNull
+        public Builder setOmega(@FloatRange(from = -3.15f, to = 3.15f) double omega) {
+            mOmega = omega;
+            return this;
+        }
+
+        /**
+         * Sets the longitude of ascending node of orbit plane at beginning of week in radians.
+         */
+        @NonNull
+        public Builder setOmega0(@FloatRange(from = -3.15f, to = 3.15f) double omega0) {
+            mOmega0 = omega0;
+            return this;
+        }
+
+        /** Sets the rate of right ascension in radians per second. */
+        @NonNull
+        public Builder setOmegaDot(@FloatRange(from = -3.1e-6f, to = 3.1e-6f) double omegaDot) {
+            mOmegaDot = omegaDot;
+            return this;
+        }
+
+        /** Sets the mean anomaly at reference time in radians. */
+        @NonNull
+        public Builder setM0(@FloatRange(from = -3.15f, to = 3.15f) double m0) {
+            mM0 = m0;
+            return this;
+        }
+
+        /** Sets the mean motion difference from computed value in radians per second. */
+        @NonNull
+        public Builder setDeltaN(@FloatRange(from = -1.18e-8f, to = 1.18e-8f) double deltaN) {
+            mDeltaN = deltaN;
+            return this;
+        }
+
+        /** Sets the second-order harmonic perturbations. */
+        @NonNull
+        public Builder setSecondOrderHarmonicPerturbation(
+                @NonNull SecondOrderHarmonicPerturbation secondOrderHarmonicPerturbation) {
+            mSecondOrderHarmonicPerturbation = secondOrderHarmonicPerturbation;
+            return this;
+        }
+
+        /** Builds a {@link KeplerianOrbitModel} instance as specified by this builder. */
+        @NonNull
+        public KeplerianOrbitModel build() {
+            return new KeplerianOrbitModel(this);
+        }
+    }
+
+    /** A class contains second-order harmonic perturbations. */
+    public static final class SecondOrderHarmonicPerturbation implements Parcelable {
+        /** Amplitude of cosine harmonic correction term to angle of inclination in radians. */
+        private final double mCic;
+
+        /** Amplitude of sine harmonic correction term to angle of inclination in radians. */
+        private final double mCis;
+
+        /** Amplitude of cosine harmonic correction term to the orbit in meters. */
+        private final double mCrc;
+
+        /** Amplitude of sine harmonic correction term to the orbit in meters. */
+        private final double mCrs;
+
+        /** Amplitude of cosine harmonic correction term to the argument of latitude in radians. */
+        private final double mCuc;
+
+        /** Amplitude of sine harmonic correction term to the argument of latitude in radians. */
+        private final double mCus;
+
+        private SecondOrderHarmonicPerturbation(Builder builder) {
+            Preconditions.checkArgumentInRange(builder.mCic, -6.11e-5f, 6.11e-5f, "Cic");
+            Preconditions.checkArgumentInRange(builder.mCis, -6.11e-5f, 6.11e-5f, "Cis");
+            Preconditions.checkArgumentInRange(builder.mCrc, -2048.0f, 2048.0f, "Crc");
+            Preconditions.checkArgumentInRange(builder.mCrs, -2048.0f, 2048.0f, "Crs");
+            Preconditions.checkArgumentInRange(builder.mCuc, -6.11e-5f, 6.11e-5f, "Cuc");
+            Preconditions.checkArgumentInRange(builder.mCus, -6.11e-5f, 6.11e-5f, "Cus");
+            mCic = builder.mCic;
+            mCrc = builder.mCrc;
+            mCis = builder.mCis;
+            mCrs = builder.mCrs;
+            mCuc = builder.mCuc;
+            mCus = builder.mCus;
+        }
+
+        /**
+         * Get the amplitude of cosine harmonic correction term to angle of inclination in radians.
+         */
+        @FloatRange(from = -6.11e-5f, to = 6.11e-5f)
+        public double getCic() {
+            return mCic;
+        }
+
+        /**
+         * Get the amplitude of sine harmonic correction term to angle of inclination in radians.
+         */
+        @FloatRange(from = -6.11e-5f, to = 6.11e-5f)
+        public double getCis() {
+            return mCis;
+        }
+
+        /** Get the amplitude of cosine harmonic correction term to the orbit in meters. */
+        @FloatRange(from = -2048.0f, to = 2048.0f)
+        public double getCrc() {
+            return mCrc;
+        }
+
+        /** Get the amplitude of sine harmonic correction term to the orbit in meters. */
+        @FloatRange(from = -2048.0f, to = 2048.0f)
+        public double getCrs() {
+            return mCrs;
+        }
+
+        /**
+         * Get the amplitude of cosine harmonic correction term to the argument of latitude in
+         * radians.
+         */
+        @FloatRange(from = -6.11e-5f, to = 6.11e-5f)
+        public double getCuc() {
+            return mCuc;
+        }
+
+        /**
+         * Get the amplitude of sine harmonic correction term to the argument of latitude in
+         * radians.
+         */
+        @FloatRange(from = -6.11e-5f, to = 6.11e-5f)
+        public double getCus() {
+            return mCus;
+        }
+
+        public static final @NonNull Creator<SecondOrderHarmonicPerturbation> CREATOR =
+                new Creator<SecondOrderHarmonicPerturbation>() {
+                    @Override
+                    @NonNull
+                    public SecondOrderHarmonicPerturbation createFromParcel(Parcel in) {
+                        final SecondOrderHarmonicPerturbation.Builder
+                                secondOrderHarmonicPerturbation =
+                                        new Builder()
+                                                .setCic(in.readDouble())
+                                                .setCis(in.readDouble())
+                                                .setCrc(in.readDouble())
+                                                .setCrs(in.readDouble())
+                                                .setCuc(in.readDouble())
+                                                .setCus(in.readDouble());
+                        return secondOrderHarmonicPerturbation.build();
+                    }
+
+                    @Override
+                    public SecondOrderHarmonicPerturbation[] newArray(int size) {
+                        return new SecondOrderHarmonicPerturbation[size];
+                    }
+                };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel parcel, int flags) {
+            parcel.writeDouble(mCic);
+            parcel.writeDouble(mCis);
+            parcel.writeDouble(mCrc);
+            parcel.writeDouble(mCrs);
+            parcel.writeDouble(mCuc);
+            parcel.writeDouble(mCus);
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            StringBuilder builder = new StringBuilder("SecondOrderHarmonicPerturbation[");
+            builder.append("cic = ").append(mCic);
+            builder.append(", cis = ").append(mCis);
+            builder.append(", crc = ").append(mCrc);
+            builder.append(", crs = ").append(mCrs);
+            builder.append(", cuc = ").append(mCuc);
+            builder.append(", cus = ").append(mCus);
+            builder.append("]");
+            return builder.toString();
+        }
+
+        /** Builder for {@link SecondOrderHarmonicPerturbation} */
+        public static final class Builder {
+            private double mCic;
+            private double mCis;
+            private double mCrc;
+            private double mCrs;
+            private double mCuc;
+            private double mCus;
+
+            /**
+             * Sets the amplitude of cosine harmonic correction term to angle of inclination in
+             * radians.
+             */
+            @NonNull
+            public Builder setCic(@FloatRange(from = -6.11e-5f, to = 6.11e-5f) double cic) {
+                mCic = cic;
+                return this;
+            }
+
+            /**
+             * Sets the amplitude of sine harmonic correction term to angle of inclination in
+             * radians.
+             */
+            @NonNull
+            public Builder setCis(@FloatRange(from = -6.11e-5f, to = 6.11e-5f) double cis) {
+                mCis = cis;
+                return this;
+            }
+
+            /** Sets the amplitude of cosine harmonic correction term to the orbit in meters. */
+            @NonNull
+            public Builder setCrc(@FloatRange(from = -2048.0f, to = 2048.0f) double crc) {
+                mCrc = crc;
+                return this;
+            }
+
+            /** Sets the amplitude of sine harmonic correction term to the orbit in meters. */
+            @NonNull
+            public Builder setCrs(@FloatRange(from = -2048.0f, to = 2048.0f) double crs) {
+                mCrs = crs;
+                return this;
+            }
+
+            /**
+             * Sets the amplitude of cosine harmonic correction term to the argument of latitude in
+             * radians.
+             */
+            @NonNull
+            public Builder setCuc(@FloatRange(from = -6.11e-5f, to = 6.11e-5f) double cuc) {
+                mCuc = cuc;
+                return this;
+            }
+
+            /**
+             * Sets the amplitude of sine harmonic correction term to the argument of latitude in
+             * radians.
+             */
+            @NonNull
+            public Builder setCus(@FloatRange(from = -6.11e-5f, to = 6.11e-5f) double cus) {
+                mCus = cus;
+                return this;
+            }
+
+            /**
+             * Builds a {@link SecondOrderHarmonicPerturbation} instance as specified by this
+             * builder.
+             */
+            @NonNull
+            public SecondOrderHarmonicPerturbation build() {
+                return new SecondOrderHarmonicPerturbation(this);
+            }
+        }
+    }
+}
diff --git a/location/java/android/location/KlobucharIonosphericModel.java b/location/java/android/location/KlobucharIonosphericModel.java
new file mode 100644
index 0000000..d239c87
--- /dev/null
+++ b/location/java/android/location/KlobucharIonosphericModel.java
@@ -0,0 +1,252 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains Klobuchar ionospheric model coefficients used by GPS, BDS, QZSS.
+ *
+ * <p>This is defined in IS-GPS-200 section 20.3.3.5.1.7.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class KlobucharIonosphericModel implements Parcelable {
+    /** Alpha0 coefficientin seconds. */
+    double mAlpha0;
+    /** Alpha1 coefficient in seconds per semi-circle. */
+    double mAlpha1;
+    /** Alpha2 coefficient in seconds per semi-circle squared. */
+    double mAlpha2;
+    /** Alpha3 coefficient in seconds per semi-circle cubed. */
+    double mAlpha3;
+    /** Beta0 coefficient in seconds. */
+    double mBeta0;
+    /** Beta1 coefficient in seconds per semi-circle. */
+    double mBeta1;
+    /** Beta2 coefficient in seconds per semi-circle squared. */
+    double mBeta2;
+    /** Beta3 coefficient in seconds per semi-circle cubed. */
+    double mBeta3;
+
+    private KlobucharIonosphericModel(Builder builder) {
+        Preconditions.checkArgumentInRange(builder.mAlpha0, -1.193e-7f, 1.193e-7f, "Alpha0");
+        Preconditions.checkArgumentInRange(builder.mAlpha1, -9.54e-7f, 9.54e-7f, "Alpha1");
+        Preconditions.checkArgumentInRange(builder.mAlpha2, -7.63e-6f, 7.63e-6f, "Alpha2");
+        Preconditions.checkArgumentInRange(builder.mAlpha3, -7.63e-6f, 7.63e-6f, "Alpha3");
+        Preconditions.checkArgumentInRange(builder.mBeta0, -262144.0f, 262144.0f, "Beta0");
+        Preconditions.checkArgumentInRange(builder.mBeta1, -2097152.0f, 2097152.0f, "Beta1");
+        Preconditions.checkArgumentInRange(builder.mBeta2, -8388608.0f, 8388608.0f, "Beta2");
+        Preconditions.checkArgumentInRange(builder.mBeta3, -8388608.0f, 8388608.0f, "Beta3");
+        mAlpha0 = builder.mAlpha0;
+        mAlpha1 = builder.mAlpha1;
+        mAlpha2 = builder.mAlpha2;
+        mAlpha3 = builder.mAlpha3;
+        mBeta0 = builder.mBeta0;
+        mBeta1 = builder.mBeta1;
+        mBeta2 = builder.mBeta2;
+        mBeta3 = builder.mBeta3;
+    }
+
+    /** Returns the alpha0 coefficient in seconds. */
+    @FloatRange(from = -1.193e-7f, to = 1.193e-7f)
+    public double getAlpha0() {
+        return mAlpha0;
+    }
+
+    /** Returns the alpha1 coefficient in seconds per semi-circle. */
+    @FloatRange(from = -9.54e-7f, to = 9.54e-7f)
+    public double getAlpha1() {
+        return mAlpha1;
+    }
+
+    /** Returns the alpha2 coefficient in seconds per semi-circle squared. */
+    @FloatRange(from = -7.63e-6f, to = 7.63e-6f)
+    public double getAlpha2() {
+        return mAlpha2;
+    }
+
+    /** Returns the alpha3 coefficient in seconds per semi-circle cubed. */
+    @FloatRange(from = -7.63e-6f, to = 7.63e-6f)
+    public double getAlpha3() {
+        return mAlpha3;
+    }
+
+    /** Returns the beta0 coefficient in seconds. */
+    @FloatRange(from = -262144.0f, to = 262144.0f)
+    public double getBeta0() {
+        return mBeta0;
+    }
+
+    /** Returns the beta1 coefficient in seconds per semi-circle. */
+    @FloatRange(from = -2097152.0f, to = 2097152.0f)
+    public double getBeta1() {
+        return mBeta1;
+    }
+
+    /** Returns the beta2 coefficient in seconds per semi-circle squared. */
+    @FloatRange(from = -8388608.0f, to = 8388608.0f)
+    public double getBeta2() {
+        return mBeta2;
+    }
+
+    /** Returns the beta3 coefficient in seconds per semi-circle cubed. */
+    @FloatRange(from = -8388608.0f, to = 8388608.0f)
+    public double getBeta3() {
+        return mBeta3;
+    }
+
+    public static final @NonNull Creator<KlobucharIonosphericModel> CREATOR =
+            new Creator<KlobucharIonosphericModel>() {
+                @Override
+                @NonNull
+                public KlobucharIonosphericModel createFromParcel(Parcel in) {
+                    return new KlobucharIonosphericModel.Builder()
+                            .setAlpha0(in.readDouble())
+                            .setAlpha1(in.readDouble())
+                            .setAlpha2(in.readDouble())
+                            .setAlpha3(in.readDouble())
+                            .setBeta0(in.readDouble())
+                            .setBeta1(in.readDouble())
+                            .setBeta2(in.readDouble())
+                            .setBeta3(in.readDouble())
+                            .build();
+                }
+                @Override
+                public KlobucharIonosphericModel[] newArray(int size) {
+                    return new KlobucharIonosphericModel[size];
+                }
+            };
+
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeDouble(mAlpha0);
+        parcel.writeDouble(mAlpha1);
+        parcel.writeDouble(mAlpha2);
+        parcel.writeDouble(mAlpha3);
+        parcel.writeDouble(mBeta0);
+        parcel.writeDouble(mBeta1);
+        parcel.writeDouble(mBeta2);
+        parcel.writeDouble(mBeta3);
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("KlobucharIonosphericModel[");
+        builder.append("alpha0 = ").append(mAlpha0);
+        builder.append(", alpha1 = ").append(mAlpha1);
+        builder.append(", alpha2 = ").append(mAlpha2);
+        builder.append(", alpha3 = ").append(mAlpha3);
+        builder.append(", beta0 = ").append(mBeta0);
+        builder.append(", beta1 = ").append(mBeta1);
+        builder.append(", beta2 = ").append(mBeta2);
+        builder.append(", beta3 = ").append(mBeta3);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /** Builder for {@link KlobucharIonosphericModel} */
+    public static final class Builder {
+        private double mAlpha0;
+        private double mAlpha1;
+        private double mAlpha2;
+        private double mAlpha3;
+        private double mBeta0;
+        private double mBeta1;
+        private double mBeta2;
+        private double mBeta3;
+
+        /** Sets the alpha0 coefficient in seconds. */
+        @NonNull
+        public Builder setAlpha0(@FloatRange(from = -1.193e-7f, to = 1.193e-7f) double alpha0) {
+            mAlpha0 = alpha0;
+            return this;
+        }
+
+        /** Sets the alpha1 coefficient in seconds per semi-circle. */
+        @NonNull
+        public Builder setAlpha1(@FloatRange(from = -9.54e-7f, to = 9.54e-7f) double alpha1) {
+            mAlpha1 = alpha1;
+            return this;
+        }
+
+        /** Sets the alpha2 coefficient in seconds per semi-circle squared. */
+        @NonNull
+        public Builder setAlpha2(@FloatRange(from = -7.63e-6f, to = 7.63e-6f) double alpha2) {
+            mAlpha2 = alpha2;
+            return this;
+        }
+
+        /** Sets the alpha3 coefficient in seconds per semi-circle cubed. */
+        @NonNull
+        public Builder setAlpha3(@FloatRange(from = -7.63e-6f, to = 7.63e-6f) double alpha3) {
+            mAlpha3 = alpha3;
+            return this;
+        }
+
+        /** Sets the beta0 coefficient in seconds. */
+        @NonNull
+        public Builder setBeta0(@FloatRange(from = -262144.0f, to = 262144.0f) double beta0) {
+            mBeta0 = beta0;
+            return this;
+        }
+
+        /** Sets the beta1 coefficient in seconds per semi-circle. */
+        @NonNull
+        public Builder setBeta1(@FloatRange(from = -2097152.0f, to = 2097152.0f) double beta1) {
+            mBeta1 = beta1;
+            return this;
+        }
+
+        /** Sets the beta2 coefficient in seconds per semi-circle squared. */
+        @NonNull
+        public Builder setBeta2(@FloatRange(from = -8388608.0f, to = 8388608.0f) double beta2) {
+            mBeta2 = beta2;
+            return this;
+        }
+
+        /** Sets the beta3 coefficient in seconds per semi-circle cubed. */
+        @NonNull
+        public Builder setBeta3(@FloatRange(from = -8388608.0f, to = 8388608.0f) double beta3) {
+            mBeta3 = beta3;
+            return this;
+        }
+
+        /** Builds a {@link KlobucharIonosphericModel} instance as specified by this builder. */
+        @NonNull
+        public KlobucharIonosphericModel build() {
+            return new KlobucharIonosphericModel(this);
+        }
+    }
+}
diff --git a/location/java/android/location/LeapSecondsModel.java b/location/java/android/location/LeapSecondsModel.java
new file mode 100644
index 0000000..bc132ad
--- /dev/null
+++ b/location/java/android/location/LeapSecondsModel.java
@@ -0,0 +1,171 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Contains the leap seconds set of parameters needed for GNSS time.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class LeapSecondsModel implements Parcelable {
+    /** Time difference due to leap seconds before the event in seconds. (UTC) */
+    private final int mLeapSeconds;
+
+    /** Time difference due to leap seconds after the event in seconds. (UTC) */
+    private final int mLeapSecondsFuture;
+
+    /** GNSS week number in which the leap second event will occur. (UTC) */
+    private final int mWeekNumberLeapSecondsFuture;
+
+    /** Day number when the next leap second will occur. */
+    private final int mDayNumberLeapSecondsFuture;
+
+    private LeapSecondsModel(Builder builder) {
+        Preconditions.checkArgument(builder.mLeapSeconds >= 0);
+        Preconditions.checkArgument(builder.mLeapSecondsFuture >= 0);
+        Preconditions.checkArgument(builder.mWeekNumberLeapSecondsFuture >= 0);
+        Preconditions.checkArgument(builder.mDayNumberLeapSecondsFuture >= 0);
+        mLeapSeconds = builder.mLeapSeconds;
+        mLeapSecondsFuture = builder.mLeapSecondsFuture;
+        mWeekNumberLeapSecondsFuture = builder.mWeekNumberLeapSecondsFuture;
+        mDayNumberLeapSecondsFuture = builder.mDayNumberLeapSecondsFuture;
+    }
+
+    /** Returns the time difference due to leap seconds before the event in seconds. (UTC) */
+    @IntRange(from = 0)
+    public int getLeapSeconds() {
+        return mLeapSeconds;
+    }
+
+    /** Returns the time difference due to leap seconds after the event in seconds. (UTC) */
+    @IntRange(from = 0)
+    public int getLeapSecondsFuture() {
+        return mLeapSecondsFuture;
+    }
+
+    /** Returns the GNSS week number in which the leap second event will occur. (UTC) */
+    @IntRange(from = 0)
+    public int getWeekNumberLeapSecondsFuture() {
+        return mWeekNumberLeapSecondsFuture;
+    }
+
+    /** Returns the day number when the next leap second will occur. */
+    @IntRange(from = 0)
+    public int getDayNumberLeapSecondsFuture() {
+        return mDayNumberLeapSecondsFuture;
+    }
+
+    public static final @NonNull Creator<LeapSecondsModel> CREATOR =
+            new Creator<LeapSecondsModel>() {
+                @Override
+                @NonNull
+                public LeapSecondsModel createFromParcel(Parcel in) {
+                    final LeapSecondsModel.Builder leapSecondsModel = new Builder();
+                    leapSecondsModel.setLeapSeconds(in.readInt());
+                    leapSecondsModel.setLeapSecondsFuture(in.readInt());
+                    leapSecondsModel.setWeekNumberLeapSecondsFuture(in.readInt());
+                    leapSecondsModel.setDayNumberLeapSecondsFuture(in.readInt());
+                    return leapSecondsModel.build();
+                }
+
+                @Override
+                public LeapSecondsModel[] newArray(int size) {
+                    return new LeapSecondsModel[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeInt(mLeapSeconds);
+        parcel.writeInt(mLeapSecondsFuture);
+        parcel.writeInt(mWeekNumberLeapSecondsFuture);
+        parcel.writeInt(mDayNumberLeapSecondsFuture);
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("LeapSecondsModel[");
+        builder.append("leapSeconds = ").append(mLeapSeconds);
+        builder.append(", leapSecondsFuture = ").append(mLeapSecondsFuture);
+        builder.append(", weekNumberLeapSecondsFuture = ").append(mWeekNumberLeapSecondsFuture);
+        builder.append(", dayNumberLeapSecondsFuture = ").append(mDayNumberLeapSecondsFuture);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /** Builder for {@link LeapSecondsModel} */
+    public static final class Builder {
+        private int mLeapSeconds;
+        private int mLeapSecondsFuture;
+        private int mWeekNumberLeapSecondsFuture;
+        private int mDayNumberLeapSecondsFuture;
+
+        /** Sets the time difference due to leap seconds before the event in seconds. (UTC) */
+        @NonNull
+        public Builder setLeapSeconds(@IntRange(from = 0) int leapSeconds) {
+            mLeapSeconds = leapSeconds;
+            return this;
+        }
+
+        /** Sets the time difference due to leap seconds after the event in seconds. (UTC) */
+        @NonNull
+        public Builder setLeapSecondsFuture(@IntRange(from = 0) int leapSecondsFuture) {
+            mLeapSecondsFuture = leapSecondsFuture;
+            return this;
+        }
+
+        /** Sets the GNSS week number in which the leap second event will occur. (UTC) */
+        @NonNull
+        public Builder setWeekNumberLeapSecondsFuture(
+                @IntRange(from = 0) int weekNumberLeapSecondsFuture) {
+            mWeekNumberLeapSecondsFuture = weekNumberLeapSecondsFuture;
+            return this;
+        }
+
+        /** Sets the day number when the next leap second will occur. */
+        @NonNull
+        public Builder setDayNumberLeapSecondsFuture(
+                @IntRange(from = 0) int dayNumberLeapSecondsFuture) {
+            mDayNumberLeapSecondsFuture = dayNumberLeapSecondsFuture;
+            return this;
+        }
+
+        /** Builds a {@link LeapSecondsModel} instance as specified by this builder. */
+        @NonNull
+        public LeapSecondsModel build() {
+            return new LeapSecondsModel(this);
+        }
+    }
+}
diff --git a/location/java/android/location/QzssAssistance.java b/location/java/android/location/QzssAssistance.java
new file mode 100644
index 0000000..9383ce3
--- /dev/null
+++ b/location/java/android/location/QzssAssistance.java
@@ -0,0 +1,282 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.location.GnssAssistance.GnssSatelliteCorrections;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class contains QZSS assistance.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class QzssAssistance implements Parcelable {
+
+    /** The QZSS almanac. */
+    @Nullable private final GnssAlmanac mAlmanac;
+
+    /** The Klobuchar ionospheric model. */
+    @Nullable private final KlobucharIonosphericModel mIonosphericModel;
+
+    /** The UTC model. */
+    @Nullable private final UtcModel mUtcModel;
+
+    /** The leap seconds model. */
+    @Nullable private final LeapSecondsModel mLeapSecondsModel;
+
+    /** The list of time models. */
+    @NonNull private final List<TimeModel> mTimeModels;
+
+    /** The list of QZSS ephemeris. */
+    @NonNull private final List<QzssSatelliteEphemeris> mSatelliteEphemeris;
+
+    /** The list of real time integrity models. */
+    @NonNull private final List<RealTimeIntegrityModel> mRealTimeIntegrityModels;
+
+    /** The list of QZSS satellite corrections. */
+    @NonNull private final List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+    private QzssAssistance(Builder builder) {
+        mAlmanac = builder.mAlmanac;
+        mIonosphericModel = builder.mIonosphericModel;
+        mUtcModel = builder.mUtcModel;
+        mLeapSecondsModel = builder.mLeapSecondsModel;
+        if (builder.mTimeModels != null) {
+            mTimeModels = Collections.unmodifiableList(new ArrayList<>(builder.mTimeModels));
+        } else {
+            mTimeModels = new ArrayList<>();
+        }
+        if (builder.mSatelliteEphemeris != null) {
+            mSatelliteEphemeris =
+                    Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteEphemeris));
+        } else {
+            mSatelliteEphemeris = new ArrayList<>();
+        }
+        if (builder.mRealTimeIntegrityModels != null) {
+            mRealTimeIntegrityModels =
+                    Collections.unmodifiableList(new ArrayList<>(builder.mRealTimeIntegrityModels));
+        } else {
+            mRealTimeIntegrityModels = new ArrayList<>();
+        }
+        if (builder.mSatelliteCorrections != null) {
+            mSatelliteCorrections =
+                    Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteCorrections));
+        } else {
+            mSatelliteCorrections = new ArrayList<>();
+        }
+    }
+
+    /** Returns the QZSS almanac. */
+    @Nullable
+    public GnssAlmanac getAlmanac() {
+        return mAlmanac;
+    }
+
+    /** Returns the Klobuchar ionospheric model. */
+    @Nullable
+    public KlobucharIonosphericModel getIonosphericModel() {
+        return mIonosphericModel;
+    }
+
+    /** Returns the UTC model. */
+    @Nullable
+    public UtcModel getUtcModel() {
+        return mUtcModel;
+    }
+
+    /** Returns the leap seconds model. */
+    @Nullable
+    public LeapSecondsModel getLeapSecondsModel() {
+        return mLeapSecondsModel;
+    }
+
+    /** Returns the list of time models. */
+    @NonNull
+    public List<TimeModel> getTimeModels() {
+        return mTimeModels;
+    }
+
+    /** Returns the list of QZSS ephemeris. */
+    @NonNull
+    public List<QzssSatelliteEphemeris> getSatelliteEphemeris() {
+        return mSatelliteEphemeris;
+    }
+
+    /** Returns the list of real time integrity models. */
+    @NonNull
+    public List<RealTimeIntegrityModel> getRealTimeIntegrityModels() {
+        return mRealTimeIntegrityModels;
+    }
+
+    /** Returns the list of QZSS satellite corrections. */
+    @NonNull
+    public List<GnssSatelliteCorrections> getSatelliteCorrections() {
+        return mSatelliteCorrections;
+    }
+
+    public static final @NonNull Creator<QzssAssistance> CREATOR =
+            new Creator<QzssAssistance>() {
+                @Override
+                @NonNull
+                public QzssAssistance createFromParcel(Parcel in) {
+                    return new QzssAssistance.Builder()
+                        .setAlmanac(in.readTypedObject(GnssAlmanac.CREATOR))
+                        .setIonosphericModel(in.readTypedObject(KlobucharIonosphericModel.CREATOR))
+                        .setUtcModel(in.readTypedObject(UtcModel.CREATOR))
+                        .setLeapSecondsModel(in.readTypedObject(LeapSecondsModel.CREATOR))
+                        .setTimeModels(in.createTypedArrayList(TimeModel.CREATOR))
+                        .setSatelliteEphemeris(
+                                in.createTypedArrayList(QzssSatelliteEphemeris.CREATOR))
+                        .setRealTimeIntegrityModels(
+                                in.createTypedArrayList(RealTimeIntegrityModel.CREATOR))
+                        .setSatelliteCorrections(
+                                in.createTypedArrayList(GnssSatelliteCorrections.CREATOR))
+                        .build();
+                }
+                @Override
+                public QzssAssistance[] newArray(int size) {
+                    return new QzssAssistance[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeTypedObject(mAlmanac, flags);
+        dest.writeTypedObject(mIonosphericModel, flags);
+        dest.writeTypedObject(mUtcModel, flags);
+        dest.writeTypedObject(mLeapSecondsModel, flags);
+        dest.writeTypedList(mTimeModels);
+        dest.writeTypedList(mSatelliteEphemeris);
+        dest.writeTypedList(mRealTimeIntegrityModels);
+        dest.writeTypedList(mSatelliteCorrections);
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("QzssAssistance[");
+        builder.append("almanac = ").append(mAlmanac);
+        builder.append(", ionosphericModel = ").append(mIonosphericModel);
+        builder.append(", utcModel = ").append(mUtcModel);
+        builder.append(", leapSecondsModel = ").append(mLeapSecondsModel);
+        builder.append(", timeModels = ").append(mTimeModels);
+        builder.append(", satelliteEphemeris = ").append(mSatelliteEphemeris);
+        builder.append(", realTimeIntegrityModels = ").append(mRealTimeIntegrityModels);
+        builder.append(", satelliteCorrections = ").append(mSatelliteCorrections);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /** Builder for {@link QzssAssistance}. */
+    public static final class Builder {
+        private GnssAlmanac mAlmanac;
+        private KlobucharIonosphericModel mIonosphericModel;
+        private UtcModel mUtcModel;
+        private LeapSecondsModel mLeapSecondsModel;
+        private List<TimeModel> mTimeModels;
+        private List<QzssSatelliteEphemeris> mSatelliteEphemeris;
+        private List<RealTimeIntegrityModel> mRealTimeIntegrityModels;
+        private List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+        /** Sets the QZSS almanac. */
+        @NonNull
+        public Builder setAlmanac(@Nullable GnssAlmanac almanac) {
+            mAlmanac = almanac;
+            return this;
+        }
+
+        /** Sets the Klobuchar ionospheric model. */
+        @NonNull
+        public Builder setIonosphericModel(@Nullable KlobucharIonosphericModel ionosphericModel) {
+            mIonosphericModel = ionosphericModel;
+            return this;
+        }
+
+        /** Sets the UTC model. */
+        @NonNull
+        public Builder setUtcModel(@Nullable UtcModel utcModel) {
+            mUtcModel = utcModel;
+            return this;
+        }
+
+        /** Sets the leap seconds model. */
+        @NonNull
+        public Builder setLeapSecondsModel(@Nullable LeapSecondsModel leapSecondsModel) {
+            mLeapSecondsModel = leapSecondsModel;
+            return this;
+        }
+
+        /** Sets the list of time models. */
+        @NonNull
+        public Builder setTimeModels(
+                @Nullable @SuppressLint("NullableCollection") List<TimeModel> timeModels) {
+            mTimeModels = timeModels;
+            return this;
+        }
+
+        /** Sets the list of QZSS ephemeris. */
+        @NonNull
+        public Builder setSatelliteEphemeris(
+                @Nullable @SuppressLint("NullableCollection")
+                        List<QzssSatelliteEphemeris> satelliteEphemeris) {
+            mSatelliteEphemeris = satelliteEphemeris;
+            return this;
+        }
+
+        /** Sets the list of real time integrity model. */
+        @NonNull
+        public Builder setRealTimeIntegrityModels(
+                @Nullable @SuppressLint("NullableCollection")
+                        List<RealTimeIntegrityModel> realTimeIntegrityModels) {
+            mRealTimeIntegrityModels = realTimeIntegrityModels;
+            return this;
+        }
+
+        /** Sets the list of QZSS satellite correction. */
+        @NonNull
+        public Builder setSatelliteCorrections(
+                @Nullable @SuppressLint("NullableCollection")
+                        List<GnssSatelliteCorrections> satelliteCorrections) {
+            mSatelliteCorrections = satelliteCorrections;
+            return this;
+        }
+
+        /** Builds a {@link QzssAssistance} instance as specified by this builder. */
+        @NonNull
+        public QzssAssistance build() {
+            return new QzssAssistance(this);
+        }
+    }
+}
diff --git a/location/java/android/location/QzssSatelliteEphemeris.java b/location/java/android/location/QzssSatelliteEphemeris.java
new file mode 100644
index 0000000..96203d9
--- /dev/null
+++ b/location/java/android/location/QzssSatelliteEphemeris.java
@@ -0,0 +1,229 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.GpsSatelliteEphemeris.GpsL2Params;
+import android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel;
+import android.location.GpsSatelliteEphemeris.GpsSatelliteHealth;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains ephemeris parameters specific to QZSS satellites.
+ *
+ * <p>This is defined in IS-QZSS-PNT section 4.1.2.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class QzssSatelliteEphemeris implements Parcelable {
+    /** Satellite PRN. */
+    private final int mPrn;
+
+    /** L2 parameters. */
+    @NonNull private final GpsL2Params mGpsL2Params;
+
+    /** Clock model. */
+    @NonNull private final GpsSatelliteClockModel mSatelliteClockModel;
+
+    /** Orbit model. */
+    @NonNull private final KeplerianOrbitModel mSatelliteOrbitModel;
+
+    /** Satellite health. */
+    @NonNull private final GpsSatelliteHealth mSatelliteHealth;
+
+    /** Ephemeris time. */
+    @NonNull private final SatelliteEphemerisTime mSatelliteEphemerisTime;
+
+    /** Returns the PRN of the satellite. */
+    @IntRange(from = 183, to = 206)
+    public int getPrn() {
+        return mPrn;
+    }
+
+    /** Returns the L2 parameters of the satellite. */
+    @NonNull
+    public GpsL2Params getGpsL2Params() {
+        return mGpsL2Params;
+    }
+
+    /** Returns the clock model of the satellite. */
+    @NonNull
+    public GpsSatelliteClockModel getSatelliteClockModel() {
+        return mSatelliteClockModel;
+    }
+
+    /** Returns the orbit model of the satellite. */
+    @NonNull
+    public KeplerianOrbitModel getSatelliteOrbitModel() {
+        return mSatelliteOrbitModel;
+    }
+
+    /** Returns the satellite health. */
+    @NonNull
+    public GpsSatelliteHealth getSatelliteHealth() {
+        return mSatelliteHealth;
+    }
+
+    /** Returns the ephemeris time. */
+    @NonNull
+    public SatelliteEphemerisTime getSatelliteEphemerisTime() {
+        return mSatelliteEphemerisTime;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeInt(mPrn);
+        parcel.writeTypedObject(mGpsL2Params, flags);
+        parcel.writeTypedObject(mSatelliteClockModel, flags);
+        parcel.writeTypedObject(mSatelliteOrbitModel, flags);
+        parcel.writeTypedObject(mSatelliteHealth, flags);
+        parcel.writeTypedObject(mSatelliteEphemerisTime, flags);
+    }
+
+    private QzssSatelliteEphemeris(Builder builder) {
+        // Allow PRN beyond the range to support potential future extensibility.
+        Preconditions.checkArgument(builder.mPrn >= 1);
+        Preconditions.checkNotNull(builder.mGpsL2Params, "GpsL2Params cannot be null");
+        Preconditions.checkNotNull(builder.mSatelliteClockModel,
+                "SatelliteClockModel cannot be null");
+        Preconditions.checkNotNull(builder.mSatelliteOrbitModel,
+                "SatelliteOrbitModel cannot be null");
+        Preconditions.checkNotNull(builder.mSatelliteHealth,
+                "SatelliteHealth cannot be null");
+        Preconditions.checkNotNull(builder.mSatelliteEphemerisTime,
+                "SatelliteEphemerisTime cannot be null");
+        mPrn = builder.mPrn;
+        mGpsL2Params = builder.mGpsL2Params;
+        mSatelliteClockModel = builder.mSatelliteClockModel;
+        mSatelliteOrbitModel = builder.mSatelliteOrbitModel;
+        mSatelliteHealth = builder.mSatelliteHealth;
+        mSatelliteEphemerisTime = builder.mSatelliteEphemerisTime;
+    }
+
+    public static final @NonNull Creator<QzssSatelliteEphemeris> CREATOR =
+            new Creator<QzssSatelliteEphemeris>() {
+                @Override
+                @NonNull
+                public QzssSatelliteEphemeris createFromParcel(Parcel in) {
+                    final QzssSatelliteEphemeris.Builder qzssSatelliteEphemeris =
+                            new Builder()
+                                    .setPrn(in.readInt())
+                                    .setGpsL2Params(in.readTypedObject(GpsL2Params.CREATOR))
+                                    .setSatelliteClockModel(
+                                            in.readTypedObject(GpsSatelliteClockModel.CREATOR))
+                                    .setSatelliteOrbitModel(
+                                            in.readTypedObject(KeplerianOrbitModel.CREATOR))
+                                    .setSatelliteHealth(
+                                            in.readTypedObject(GpsSatelliteHealth.CREATOR))
+                                    .setSatelliteEphemerisTime(
+                                            in.readTypedObject(SatelliteEphemerisTime.CREATOR));
+                    return qzssSatelliteEphemeris.build();
+                }
+
+                @Override
+                public QzssSatelliteEphemeris[] newArray(int size) {
+                    return new QzssSatelliteEphemeris[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("QzssSatelliteEphemeris[");
+        builder.append("prn=").append(mPrn);
+        builder.append(", gpsL2Params=").append(mGpsL2Params);
+        builder.append(", satelliteClockModel=").append(mSatelliteClockModel);
+        builder.append(", satelliteOrbitModel=").append(mSatelliteOrbitModel);
+        builder.append(", satelliteHealth=").append(mSatelliteHealth);
+        builder.append(", satelliteEphemerisTime=").append(mSatelliteEphemerisTime);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /** Builder for {@link QzssSatelliteEphemeris}. */
+    public static final class Builder {
+        private int mPrn;
+        private GpsL2Params mGpsL2Params;
+        private GpsSatelliteClockModel mSatelliteClockModel;
+        private KeplerianOrbitModel mSatelliteOrbitModel;
+        private GpsSatelliteHealth mSatelliteHealth;
+        private SatelliteEphemerisTime mSatelliteEphemerisTime;
+
+        /** Sets the PRN of the satellite. */
+        @NonNull
+        public Builder setPrn(@IntRange(from = 183, to = 206) int prn) {
+            mPrn = prn;
+            return this;
+        }
+
+        /** Sets the L2 parameters of the satellite. */
+        @NonNull
+        public Builder setGpsL2Params(@NonNull GpsL2Params gpsL2Params) {
+            mGpsL2Params = gpsL2Params;
+            return this;
+        }
+
+        /** Sets the clock model of the satellite. */
+        @NonNull
+        public Builder setSatelliteClockModel(@NonNull GpsSatelliteClockModel satelliteClockModel) {
+            mSatelliteClockModel = satelliteClockModel;
+            return this;
+        }
+
+        /** Sets the orbit model of the satellite. */
+        @NonNull
+        public Builder setSatelliteOrbitModel(@NonNull KeplerianOrbitModel satelliteOrbitModel) {
+            mSatelliteOrbitModel = satelliteOrbitModel;
+            return this;
+        }
+
+        /** Sets the satellite health. */
+        @NonNull
+        public Builder setSatelliteHealth(@NonNull GpsSatelliteHealth satelliteHealth) {
+            mSatelliteHealth = satelliteHealth;
+            return this;
+        }
+
+        /** Sets the ephemeris time. */
+        @NonNull
+        public Builder setSatelliteEphemerisTime(
+                @NonNull SatelliteEphemerisTime satelliteEphemerisTime) {
+            mSatelliteEphemerisTime = satelliteEphemerisTime;
+            return this;
+        }
+
+        /** Builds a {@link QzssSatelliteEphemeris} instance as specified by this builder. */
+        @NonNull
+        public QzssSatelliteEphemeris build() {
+            return new QzssSatelliteEphemeris(this);
+        }
+    }
+}
diff --git a/location/java/android/location/RealTimeIntegrityModel.java b/location/java/android/location/RealTimeIntegrityModel.java
new file mode 100644
index 0000000..d268926
--- /dev/null
+++ b/location/java/android/location/RealTimeIntegrityModel.java
@@ -0,0 +1,284 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains the real time integrity status of a GNSS satellite based on notice advisory.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class RealTimeIntegrityModel implements Parcelable {
+    /**
+     * Pseudo-random or satellite ID number for the satellite,
+     * a.k.a. Space Vehicle (SV), or OSN number for Glonass.
+     *
+     * <p>The distinction is made by looking at the constellation field. Values
+     * must be in the range of:
+     *
+     * <p> - GPS: 1-32
+     * <p> - GLONASS: 1-25
+     * <p> - QZSS: 183-206
+     * <p> - Galileo: 1-36
+     * <p> - Beidou: 1-63
+     */
+    private final int mSvid;
+
+    /** Indicates whether the satellite is currently usable for navigation. */
+    private final boolean mUsable;
+
+    /** UTC timestamp (in seconds) when the advisory was published. */
+    private final long mPublishDateSeconds;
+
+    /** UTC timestamp (in seconds) for the start of the event. */
+    private final long mStartDateSeconds;
+
+    /** UTC timestamp (in seconds) for the end of the event. */
+    private final long mEndDateSeconds;
+
+    /**
+     * Abbreviated type of the advisory, providing a concise summary of the event.
+     *
+     * <p>This field follows different definitions depending on the GNSS constellation:
+     * <p> - GPS: See NANU type definitions(https://www.navcen.uscg.gov/nanu-abbreviations-and-descriptions)
+     * <p> - Galileo: See NAGU type definitions(https://www.gsc-europa.eu/system-service-status/nagu-information)
+     * <p> - QZSS: See NAQU type definitions](https://sys.qzss.go.jp/dod/en/naqu/type.html)
+     * <p> - BeiDou: Not used; set to an empty string.
+     */
+    @NonNull private final String mAdvisoryType;
+
+    /**
+     *  Unique identifier for the advisory within its constellation's system.
+     *
+     *  <p>For BeiDou, this is not used and should be an empty string.
+     */
+    @NonNull private final String mAdvisoryNumber;
+
+    private RealTimeIntegrityModel(Builder builder) {
+        // Allow SV ID beyond the range to support potential future extensibility.
+        Preconditions.checkArgument(builder.mSvid >= 1);
+        Preconditions.checkArgument(builder.mPublishDateSeconds > 0);
+        Preconditions.checkArgument(builder.mStartDateSeconds > 0);
+        Preconditions.checkArgument(builder.mEndDateSeconds > 0);
+        Preconditions.checkNotNull(builder.mAdvisoryType, "AdvisoryType cannot be null");
+        Preconditions.checkNotNull(builder.mAdvisoryNumber, "AdvisoryNumber cannot be null");
+        mSvid = builder.mSvid;
+        mUsable = builder.mUsable;
+        mPublishDateSeconds = builder.mPublishDateSeconds;
+        mStartDateSeconds = builder.mStartDateSeconds;
+        mEndDateSeconds = builder.mEndDateSeconds;
+        mAdvisoryType = builder.mAdvisoryType;
+        mAdvisoryNumber = builder.mAdvisoryNumber;
+    }
+
+    /**
+     * Returns the Pseudo-random or satellite ID number for the satellite,
+     * a.k.a. Space Vehicle (SV), or OSN number for Glonass.
+     *
+     * <p>The distinction is made by looking at the constellation field. Values
+     * must be in the range of:
+     *
+     * <p> - GPS: 1-32
+     * <p> - GLONASS: 1-25
+     * <p> - QZSS: 183-206
+     * <p> - Galileo: 1-36
+     * <p> - Beidou: 1-63
+     */
+    @IntRange(from = 1, to = 206)
+    public int getSvid() {
+        return mSvid;
+    }
+
+    /** Returns whether the satellite is usable or not. */
+    public boolean isUsable() {
+        return mUsable;
+    }
+
+    /** Returns the UTC timestamp (in seconds) when the advisory was published */
+    @IntRange(from = 0)
+    public long getPublishDateSeconds() {
+        return mPublishDateSeconds;
+    }
+
+    /** Returns UTC timestamp (in seconds) for the start of the event. */
+    @IntRange(from = 0)
+    public long getStartDateSeconds() {
+        return mStartDateSeconds;
+    }
+
+    /** Returns UTC timestamp (in seconds) for the end of the event. */
+    @IntRange(from = 0)
+    public long getEndDateSeconds() {
+        return mEndDateSeconds;
+    }
+
+    /** Returns the abbreviated type of notice advisory. */
+    @NonNull
+    public String getAdvisoryType() {
+        return mAdvisoryType;
+    }
+
+    /** Returns the unique identifier for the advisory. */
+    @NonNull
+    public String getAdvisoryNumber() {
+        return mAdvisoryNumber;
+    }
+
+    public static final @NonNull Creator<RealTimeIntegrityModel> CREATOR =
+            new Creator<RealTimeIntegrityModel>() {
+                @Override
+                @NonNull
+                public RealTimeIntegrityModel createFromParcel(Parcel in) {
+                    RealTimeIntegrityModel realTimeIntegrityModel =
+                            new RealTimeIntegrityModel.Builder()
+                                    .setSvid(in.readInt())
+                                    .setUsable(in.readBoolean())
+                                    .setPublishDateSeconds(in.readLong())
+                                    .setStartDateSeconds(in.readLong())
+                                    .setEndDateSeconds(in.readLong())
+                                    .setAdvisoryType(in.readString8())
+                                    .setAdvisoryNumber(in.readString8())
+                                    .build();
+                    return realTimeIntegrityModel;
+                }
+
+                @Override
+                public RealTimeIntegrityModel[] newArray(int size) {
+                    return new RealTimeIntegrityModel[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeInt(mSvid);
+        parcel.writeBoolean(mUsable);
+        parcel.writeLong(mPublishDateSeconds);
+        parcel.writeLong(mStartDateSeconds);
+        parcel.writeLong(mEndDateSeconds);
+        parcel.writeString8(mAdvisoryType);
+        parcel.writeString8(mAdvisoryNumber);
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("RealTimeIntegrityModel[");
+        builder.append("svid = ").append(mSvid);
+        builder.append(", usable = ").append(mUsable);
+        builder.append(", publishDateSeconds = ").append(mPublishDateSeconds);
+        builder.append(", startDateSeconds = ").append(mStartDateSeconds);
+        builder.append(", endDateSeconds = ").append(mEndDateSeconds);
+        builder.append(", advisoryType = ").append(mAdvisoryType);
+        builder.append(", advisoryNumber = ").append(mAdvisoryNumber);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /** Builder for {@link RealTimeIntegrityModel} */
+    public static final class Builder {
+        private int mSvid;
+        private boolean mUsable;
+        private long mPublishDateSeconds;
+        private long mStartDateSeconds;
+        private long mEndDateSeconds;
+        private String mAdvisoryType;
+        private String mAdvisoryNumber;
+
+        /**
+         * Sets the Pseudo-random or satellite ID number for the satellite,
+         * a.k.a. Space Vehicle (SV), or OSN number for Glonass.
+         *
+         * <p>The distinction is made by looking at the constellation field. Values
+         * must be in the range of:
+         *
+         * <p> - GPS: 1-32
+         * <p> - GLONASS: 1-25
+         * <p> - QZSS: 183-206
+         * <p> - Galileo: 1-36
+         * <p> - Beidou: 1-63
+         */
+        @NonNull
+        public Builder setSvid(@IntRange(from = 1, to = 206) int svid) {
+            mSvid = svid;
+            return this;
+        }
+
+        /** Sets whether the satellite is usable or not. */
+        @NonNull
+        public Builder setUsable(boolean usable) {
+            mUsable = usable;
+            return this;
+        }
+
+        /** Sets the UTC timestamp (in seconds) when the advisory was published. */
+        @NonNull
+        public Builder setPublishDateSeconds(@IntRange(from = 0) long publishDateSeconds) {
+            mPublishDateSeconds = publishDateSeconds;
+            return this;
+        }
+
+        /** Sets the UTC timestamp (in seconds) for the start of the event. */
+        @NonNull
+        public Builder setStartDateSeconds(@IntRange(from = 0) long startDateSeconds) {
+            mStartDateSeconds = startDateSeconds;
+            return this;
+        }
+
+        /** Sets the UTC timestamp (in seconds) for the end of the event. */
+        @NonNull
+        public Builder setEndDateSeconds(@IntRange(from = 0) long endDateSeconds) {
+            mEndDateSeconds = endDateSeconds;
+            return this;
+        }
+
+        /** Sets the abbreviated type of notice advisory. */
+        @NonNull
+        public Builder setAdvisoryType(@NonNull String advisoryType) {
+            mAdvisoryType = advisoryType;
+            return this;
+        }
+
+        /** Sets the unique identifier for the advisory. */
+        @NonNull
+        public Builder setAdvisoryNumber(@NonNull String advisoryNumber) {
+            mAdvisoryNumber = advisoryNumber;
+            return this;
+        }
+
+        /** Builds a {@link RealTimeIntegrityModel} instance as specified by this builder. */
+        @NonNull
+        public RealTimeIntegrityModel build() {
+            return new RealTimeIntegrityModel(this);
+        }
+    }
+}
diff --git a/location/java/android/location/SatelliteEphemerisTime.java b/location/java/android/location/SatelliteEphemerisTime.java
new file mode 100644
index 0000000..0ab3acf
--- /dev/null
+++ b/location/java/android/location/SatelliteEphemerisTime.java
@@ -0,0 +1,151 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains time of ephemeris for GPS, Galileo, and QZSS.
+ *
+ * <p>For GPS, this is defined in IS-GPS-200, section 20.3.3.4.1.
+ * <p>For Galileo, this is defined in Galileo-OS-SIS-ICD, section 5.1.2, 5.1.9.2.
+ * <p>For QZSS, this is defined in IS-QZSS-200, section 4.1.2.4.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class SatelliteEphemerisTime implements Parcelable {
+    /** The issue of ephemeris data. */
+    private final int mIode;
+
+    /** The satellite week number without rollover. */
+    private final int mWeekNumber;
+
+    /** The broadcast time of ephemeris in GNSS time of week in seconds. */
+    private final int mToeSeconds;
+
+    private SatelliteEphemerisTime(Builder builder) {
+        Preconditions.checkArgumentInRange(builder.mIode, 0, 1023, "Iode");
+        Preconditions.checkArgument(builder.mWeekNumber >= 0);
+        Preconditions.checkArgumentInRange(builder.mToeSeconds, 0, 604799, "ToeSeconds");
+        mIode = builder.mIode;
+        mWeekNumber = builder.mWeekNumber;
+        mToeSeconds = builder.mToeSeconds;
+    }
+
+    /** Returns the issue of ephemeris data. */
+    @IntRange(from = 0, to = 1023)
+    public int getIode() {
+        return mIode;
+    }
+
+    /** Returns the satellite week number without rollover. */
+    @IntRange(from = 0)
+    public int getWeekNumber() {
+        return mWeekNumber;
+    }
+
+    /** Returns the broadcast time of ephemeris in GNSS time of week in seconds. */
+    @IntRange(from = 0, to = 604799)
+    public int getToeSeconds() {
+        return mToeSeconds;
+    }
+
+    public static final @NonNull Creator<SatelliteEphemerisTime> CREATOR =
+            new Creator<SatelliteEphemerisTime>() {
+                @Override
+                public SatelliteEphemerisTime createFromParcel(Parcel in) {
+                    final SatelliteEphemerisTime.Builder satelliteEphemerisTime =
+                            new Builder()
+                                    .setIode(in.readInt())
+                                    .setWeekNumber(in.readInt())
+                                    .setToeSeconds(in.readInt());
+                    return satelliteEphemerisTime.build();
+                }
+
+                @Override
+                public SatelliteEphemerisTime[] newArray(int size) {
+                    return new SatelliteEphemerisTime[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeInt(mIode);
+        parcel.writeInt(mWeekNumber);
+        parcel.writeInt(mToeSeconds);
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("SatelliteEphemerisTime[");
+        builder.append("iode = ").append(mIode);
+        builder.append(", weekNumber = ").append(mWeekNumber);
+        builder.append(", toeSeconds = ").append(mToeSeconds);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /** Builder for {@link SatelliteEphemerisTime}. */
+    public static final class Builder {
+        private int mIode;
+        private int mWeekNumber;
+        private int mToeSeconds;
+
+        /** Sets the issue of ephemeris data. */
+        @NonNull
+        public Builder setIode(@IntRange(from = 0, to = 1023) int iode) {
+            mIode = iode;
+            return this;
+        }
+
+        /** Sets the satellite week number without rollover. */
+        @NonNull
+        public Builder setWeekNumber(@IntRange(from = 0) int weekNumber) {
+            mWeekNumber = weekNumber;
+            return this;
+        }
+
+        /** Sets the broadcast time of ephemeris in GNSS time of week in seconds. */
+        @NonNull
+        public Builder setToeSeconds(@IntRange(from = 0, to = 604799) int toeSeconds) {
+            mToeSeconds = toeSeconds;
+            return this;
+        }
+
+        /** Builds a {@link SatelliteEphemerisTime} instance as specified by this builder. */
+        @NonNull
+        public SatelliteEphemerisTime build() {
+            return new SatelliteEphemerisTime(this);
+        }
+    }
+}
diff --git a/location/java/android/location/TimeModel.java b/location/java/android/location/TimeModel.java
new file mode 100644
index 0000000..380f7b8
--- /dev/null
+++ b/location/java/android/location/TimeModel.java
@@ -0,0 +1,208 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.GnssStatus.ConstellationType;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains the GNSS-GNSS system time offset between the GNSS system time.
+ *
+ * <p>This is defined in IS-GPS-200 section 30.3.3.8.2.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class TimeModel implements Parcelable {
+    /*
+     * Model represents parameters to convert from current GNSS to GNSS system
+     * time indicated by toGnss.
+     */
+    private final @ConstellationType int mToGnss;
+
+    /** Bias coefficient of GNSS time scale relative to GNSS time scale in seconds. */
+    private final double mA0;
+
+    /** Drift coefficient of GNSS time scale relative to GNSS time scale in seconds per second. */
+    private final double mA1;
+
+    /** GNSS time of week in seconds. */
+    private final int mTimeOfWeek;
+
+    /** Week number of the GNSS time. */
+    private final int mWeekNumber;
+
+    private TimeModel(Builder builder) {
+        Preconditions.checkArgumentInRange(
+                builder.mToGnss,
+                GnssStatus.CONSTELLATION_UNKNOWN,
+                GnssStatus.CONSTELLATION_COUNT,
+                "ToGnss");
+        Preconditions.checkArgumentInRange(builder.mA0, -1.0f, 1.0f, "A0");
+        Preconditions.checkArgumentInRange(builder.mA1, -3.28e-6f, 3.28e-6f, "A1");
+        Preconditions.checkArgumentInRange(builder.mTimeOfWeek, 0, 604800, "TimeOfWeek");
+        Preconditions.checkArgument(builder.mWeekNumber >= 0);
+        mToGnss = builder.mToGnss;
+        mA0 = builder.mA0;
+        mA1 = builder.mA1;
+        mTimeOfWeek = builder.mTimeOfWeek;
+        mWeekNumber = builder.mWeekNumber;
+    }
+
+    /** Returns the constellation type to convert from current GNSS system time. */
+    @ConstellationType
+    public int getToGnss() {
+        return mToGnss;
+    }
+
+    /** Returns the bias coefficient of GNSS time scale relative to GNSS time scale in seconds. */
+    @FloatRange(from = -1.0f, to = 1.0f)
+    public double getA0() {
+        return mA0;
+    }
+
+    /**
+     * Returns the drift coefficient of GNSS time scale relative to GNSS time scale in seconds per
+     * second.
+     */
+    @FloatRange(from = -3.28e-6f, to = 3.28e-6f)
+    public double getA1() {
+        return mA1;
+    }
+
+    /** Returns the GNSS time of week in seconds. */
+    @IntRange(from = 0, to = 604800)
+    public int getTimeOfWeek() {
+        return mTimeOfWeek;
+    }
+
+    /** Returns the week number of the GNSS time. */
+    @IntRange(from = 0)
+    public int getWeekNumber() {
+        return mWeekNumber;
+    }
+
+    public static final @NonNull Creator<TimeModel> CREATOR =
+            new Creator<TimeModel>() {
+                @Override
+                public TimeModel createFromParcel(@NonNull Parcel source) {
+                    return new TimeModel.Builder()
+                            .setToGnss(source.readInt())
+                            .setA0(source.readDouble())
+                            .setA1(source.readDouble())
+                            .setTimeOfWeek(source.readInt())
+                            .setWeekNumber(source.readInt())
+                            .build();
+                }
+
+                @Override
+                public TimeModel[] newArray(int size) {
+                    return new TimeModel[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("TimeModel[");
+        builder.append("toGnss = ").append(mToGnss);
+        builder.append(", a0 = ").append(mA0);
+        builder.append(", a1 = ").append(mA1);
+        builder.append(", timeOfWeek = ").append(mTimeOfWeek);
+        builder.append(", weekNumber = ").append(mWeekNumber);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mToGnss);
+        dest.writeDouble(mA0);
+        dest.writeDouble(mA1);
+        dest.writeInt(mTimeOfWeek);
+        dest.writeInt(mWeekNumber);
+    }
+
+    /** Builder for {@link TimeModel} */
+    public static final class Builder {
+
+        private @ConstellationType int mToGnss;
+        private double mA0;
+        private double mA1;
+        private int mTimeOfWeek;
+        private int mWeekNumber;
+
+        /** Sets the constellation type to convert from current GNSS system time. */
+        @NonNull
+        public Builder setToGnss(@ConstellationType int toGnss) {
+            mToGnss = toGnss;
+            return this;
+        }
+
+        /** Sets the bias coefficient of GNSS time scale relative to GNSS time scale in seconds. */
+        @NonNull
+        public Builder setA0(@FloatRange(from = -1.0f, to = 1.0f) double a0) {
+            mA0 = a0;
+            return this;
+        }
+
+        /**
+         * Sets the drift coefficient of GNSS time scale relative to GNSS time scale in seconds per
+         * second.
+         */
+        @NonNull
+        public Builder setA1(@FloatRange(from = -3.28e-6f, to = 3.28e-6f) double a1) {
+            mA1 = a1;
+            return this;
+        }
+
+        /** Sets the GNSS time of week in seconds. */
+        @NonNull
+        public Builder setTimeOfWeek(@IntRange(from = 0, to = 604800) int timeOfWeek) {
+            mTimeOfWeek = timeOfWeek;
+            return this;
+        }
+
+        /** Sets the week number of the GNSS time. */
+        @NonNull
+        public Builder setWeekNumber(@IntRange(from = 0) int weekNumber) {
+            mWeekNumber = weekNumber;
+            return this;
+        }
+
+        /** Builds the {@link TimeModel} object. */
+        @NonNull
+        public TimeModel build() {
+            return new TimeModel(this);
+        }
+    }
+}
diff --git a/location/java/android/location/UtcModel.java b/location/java/android/location/UtcModel.java
new file mode 100644
index 0000000..6dc633d
--- /dev/null
+++ b/location/java/android/location/UtcModel.java
@@ -0,0 +1,176 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains parameters to convert from current GNSS time to UTC time.
+ *
+ * <p>This is defined in RINEX 3.05 "TIME SYSTEM CORR" in table A5.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class UtcModel implements Parcelable {
+    /** Bias coefficient of GNSS time scale relative to UTC time scale in seconds. */
+    private final double mA0;
+
+    /** Drift coefficient of GNSS time scale relative to UTC time scale in seconds per second. */
+    private final double mA1;
+
+    /** Reference GNSS time of week in seconds. */
+    private final int mTimeOfWeek;
+
+    /** Reference GNSS week number. */
+    private final int mWeekNumber;
+
+    private UtcModel(Builder builder) {
+        Preconditions.checkArgumentInRange(builder.mA0, -2.0f, 2.0f, "A0");
+        Preconditions.checkArgumentInRange(builder.mA1, -7.45e-9f, 7.45e-9f, "A1");
+        Preconditions.checkArgumentInRange(builder.mTimeOfWeek, 0, 604800, "TimeOfWeek");
+        Preconditions.checkArgument(builder.mWeekNumber >= 0);
+        mA0 = builder.mA0;
+        mA1 = builder.mA1;
+        mTimeOfWeek = builder.mTimeOfWeek;
+        mWeekNumber = builder.mWeekNumber;
+    }
+
+    /** Returns the bias coefficient of GNSS time scale relative to UTC time scale in seconds. */
+    @FloatRange(from = -2.0f, to = 2.0f)
+    public double getA0() {
+        return mA0;
+    }
+
+    /**
+     * Returns the drift coefficient of GNSS time scale relative to UTC time scale in seconds per
+     * second.
+     */
+    @FloatRange(from = -7.45e-9f, to = 7.45e-9f)
+    public double getA1() {
+        return mA1;
+    }
+
+    /** Returns the reference GNSS time of week in seconds. */
+    @IntRange(from = 0, to = 604800)
+    public int getTimeOfWeek() {
+        return mTimeOfWeek;
+    }
+
+    /** Returns the reference GNSS week number. */
+    @IntRange(from = 0)
+    public int getWeekNumber() {
+        return mWeekNumber;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+    @Override
+    @NonNull
+    public String toString() {
+        StringBuilder builder = new StringBuilder("UtcModel[");
+        builder.append("a0 = ").append(mA0);
+        builder.append(", a1 = ").append(mA1);
+        builder.append(", timeOfWeek = ").append(mTimeOfWeek);
+        builder.append(", weekNumber = ").append(mWeekNumber);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeDouble(mA0);
+        dest.writeDouble(mA1);
+        dest.writeInt(mTimeOfWeek);
+        dest.writeInt(mWeekNumber);
+    }
+
+    public static final @NonNull Creator<UtcModel> CREATOR =
+            new Creator<UtcModel>() {
+                @Override
+                public UtcModel createFromParcel(@NonNull Parcel source) {
+                    return new UtcModel.Builder()
+                            .setA0(source.readDouble())
+                            .setA1(source.readDouble())
+                            .setTimeOfWeek(source.readInt())
+                            .setWeekNumber(source.readInt())
+                            .build();
+                }
+
+                @Override
+                public UtcModel[] newArray(int size) {
+                    return new UtcModel[size];
+                }
+            };
+
+    /** Builder for {@link UtcModel}. */
+    public static final class Builder {
+        private double mA0;
+        private double mA1;
+        private int mTimeOfWeek;
+        private int mWeekNumber;
+
+        /** Sets the bias coefficient of GNSS time scale relative to UTC time scale in seconds. */
+        @NonNull
+        public Builder setA0(@FloatRange(from = -2.0f, to = 2.0f) double a0) {
+            mA0 = a0;
+            return this;
+        }
+
+        /**
+         * Sets the drift coefficient of GNSS time scale relative to UTC time scale in seconds per
+         * second.
+         */
+        @NonNull
+        public Builder setA1(@FloatRange(from = -7.45e-9f, to = 7.45e-9f) double a1) {
+            mA1 = a1;
+            return this;
+        }
+
+        /** Sets the reference GNSS time of week in seconds. */
+        @NonNull
+        public Builder setTimeOfWeek(@IntRange(from = 0, to = 604800) int timeOfWeek) {
+            mTimeOfWeek = timeOfWeek;
+            return this;
+        }
+
+        /** Sets the reference GNSS week number. */
+        @NonNull
+        public Builder setWeekNumber(@IntRange(from = 0) int weekNumber) {
+            mWeekNumber = weekNumber;
+            return this;
+        }
+
+        /** Builds a {@link UtcModel} instance as specified by this builder. */
+        @NonNull
+        public UtcModel build() {
+            return new UtcModel(this);
+        }
+    }
+}
diff --git a/location/java/android/location/flags/location.aconfig b/location/java/android/location/flags/location.aconfig
index 5395206..c02cc80 100644
--- a/location/java/android/location/flags/location.aconfig
+++ b/location/java/android/location/flags/location.aconfig
@@ -161,3 +161,10 @@
     description: "Flag for gating the density-based coarse locations"
     bug: "376198890"
 }
+
+flag {
+    name: "gnss_assistance_interface"
+    namespace: "location"
+    description: "Flag for GNSS assistance interface"
+    bug: "209078566"
+}
\ No newline at end of file
diff --git a/media/java/android/media/IMediaRoute2ProviderService.aidl b/media/java/android/media/IMediaRoute2ProviderService.aidl
index eee3d22..714cacb 100644
--- a/media/java/android/media/IMediaRoute2ProviderService.aidl
+++ b/media/java/android/media/IMediaRoute2ProviderService.aidl
@@ -33,6 +33,23 @@
 
     void requestCreateSession(long requestId, String packageName, String routeId,
             in @nullable Bundle sessionHints);
+    /**
+     * Requests the creation of a system media routing session.
+     *
+     * @param requestId The id of the request.
+     * @param uid The uid of the package whose media to route, or
+     *     {@link android.os.Process#INVALID_UID} if routing should not be restricted to a specific
+     *     uid.
+     * @param packageName The name of the package whose media to route.
+     * @param routeId The id of the route to be initially selected.
+     * @param sessionHints An optional bundle with parameters.
+     */
+    void requestCreateSystemMediaSession(
+            long requestId,
+            int uid,
+            String packageName,
+            String routeId,
+            in @nullable Bundle sessionHints);
     void selectRoute(long requestId, String sessionId, String routeId);
     void deselectRoute(long requestId, String sessionId, String routeId);
     void transferToRoute(long requestId, String sessionId, String routeId);
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index a3ad340..037b97a 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -917,6 +917,17 @@
     }
 
     /**
+     * Returns whether this route supports routing of the system media.
+     *
+     * @hide
+     */
+    public boolean supportsSystemMediaRouting() {
+        return (mRoutingTypeFlags
+                        & (FLAG_ROUTING_TYPE_SYSTEM_VIDEO | FLAG_ROUTING_TYPE_SYSTEM_AUDIO))
+                != 0;
+    }
+
+    /**
      * Returns true if the route info has all of the required field.
      * A route is valid if and only if it is obtained from
      * {@link com.android.server.media.MediaRouterService}.
diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java
index 547099f..09f40e0 100644
--- a/media/java/android/media/MediaRoute2ProviderService.java
+++ b/media/java/android/media/MediaRoute2ProviderService.java
@@ -18,14 +18,21 @@
 
 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 
+import static java.util.Objects.requireNonNull;
+
+import android.Manifest;
 import android.annotation.CallSuper;
 import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.app.Service;
 import android.content.Intent;
+import android.media.audiopolicy.AudioMix;
+import android.media.audiopolicy.AudioMixingRule;
+import android.media.audiopolicy.AudioPolicy;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -36,6 +43,7 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.util.LongSparseArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.media.flags.Flags;
@@ -47,7 +55,6 @@
 import java.util.Collection;
 import java.util.Deque;
 import java.util.List;
-import java.util.Objects;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
@@ -83,8 +90,7 @@
     public static final String SERVICE_INTERFACE = "android.media.MediaRoute2ProviderService";
 
     /**
-     * {@link Intent} action that indicates that the declaring service supports routing of the
-     * system media.
+     * A category that indicates that the declaring service supports routing of the system media.
      *
      * <p>Providers must include this action if they intend to publish routes that support the
      * system media, as described by {@link MediaRoute2Info#getSupportedRoutingTypes()}.
@@ -94,7 +100,7 @@
      */
     // TODO: b/362507305 - Unhide once the implementation and CTS are in place.
     @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
-    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    @SdkConstant(SdkConstant.SdkConstantType.INTENT_CATEGORY)
     public static final String SERVICE_INTERFACE_SYSTEM_MEDIA =
             "android.media.MediaRoute2ProviderService.SYSTEM_MEDIA";
 
@@ -165,6 +171,16 @@
     @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
     public static final int REASON_UNIMPLEMENTED = 5;
 
+    /**
+     * The request has failed because the provider has failed to route system media.
+     *
+     * @see #notifyRequestFailed
+     * @hide
+     */
+    // TODO: b/362507305 - Unhide once the implementation and CTS are in place.
+    @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
+    public static final int REASON_FAILED_TO_REROUTE_SYSTEM_MEDIA = 6;
+
     /** @hide */
     @IntDef(
             prefix = "REASON_",
@@ -174,7 +190,8 @@
                 REASON_NETWORK_ERROR,
                 REASON_ROUTE_NOT_AVAILABLE,
                 REASON_INVALID_COMMAND,
-                REASON_UNIMPLEMENTED
+                REASON_UNIMPLEMENTED,
+                REASON_FAILED_TO_REROUTE_SYSTEM_MEDIA
             })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Reason {}
@@ -187,15 +204,28 @@
     private final AtomicBoolean mStatePublishScheduled = new AtomicBoolean(false);
     private final AtomicBoolean mSessionUpdateScheduled = new AtomicBoolean(false);
     private MediaRoute2ProviderServiceStub mStub;
+    /** Populated by system_server in {@link #setCallback}. Monotonically non-null. */
     private IMediaRoute2ProviderServiceCallback mRemoteCallback;
     private volatile MediaRoute2ProviderInfo mProviderInfo;
 
     @GuardedBy("mRequestIdsLock")
     private final Deque<Long> mRequestIds = new ArrayDeque<>(MAX_REQUEST_IDS_SIZE);
 
+    /**
+     * Maps system media session creation request ids to a package uid whose media to route. The
+     * value may be {@link Process#INVALID_UID} for routing sessions that don't affect a specific
+     * package (for example, if they affect the entire system).
+     */
+    @GuardedBy("mRequestIdsLock")
+    private final LongSparseArray<Integer> mSystemMediaSessionCreationRequests =
+            new LongSparseArray<>();
+
     @GuardedBy("mSessionLock")
     private final ArrayMap<String, RoutingSessionInfo> mSessionInfos = new ArrayMap<>();
 
+    @GuardedBy("mSessionLock")
+    private final ArrayMap<String, MediaStreams> mOngoingMediaStreams = new ArrayMap<>();
+
     public MediaRoute2ProviderService() {
         mHandler = new Handler(Looper.getMainLooper());
     }
@@ -282,7 +312,7 @@
      */
     public final void notifySessionCreated(long requestId,
             @NonNull RoutingSessionInfo sessionInfo) {
-        Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+        requireNonNull(sessionInfo, "sessionInfo must not be null");
 
         if (DEBUG) {
             Log.d(TAG, "notifySessionCreated: Creating a session. requestId=" + requestId
@@ -326,17 +356,129 @@
      * @param formats the {@link MediaStreamsFormats} that describes the format for the {@link
      *     MediaStreams} to return.
      * @return a {@link MediaStreams} instance that holds the media streams to route as part of the
-     *     newly created routing session.
+     *     newly created routing session. May be null if system media capture failed, in which case
+     *     you can ignore the return value, as you will receive a call to {@link #onReleaseSession}
+     *     where you can clean up this session
      * @hide
      */
     // TODO: b/362507305 - Unhide once the implementation and CTS are in place.
     @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
-    @NonNull
+    @RequiresPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
+    @Nullable
     public final MediaStreams notifySystemMediaSessionCreated(
             long requestId,
             @NonNull RoutingSessionInfo sessionInfo,
             @NonNull MediaStreamsFormats formats) {
-        throw new UnsupportedOperationException();
+        requireNonNull(sessionInfo, "sessionInfo must not be null");
+        requireNonNull(formats, "formats must not be null");
+        if (DEBUG) {
+            Log.d(
+                    TAG,
+                    "notifySystemMediaSessionCreated: Creating a session. requestId="
+                            + requestId
+                            + ", sessionInfo="
+                            + sessionInfo);
+        }
+
+        Integer uid;
+        synchronized (mRequestIdsLock) {
+            uid = mSystemMediaSessionCreationRequests.get(requestId);
+            mSystemMediaSessionCreationRequests.remove(requestId);
+        }
+
+        if (uid == null) {
+            throw new IllegalStateException(
+                    "Unexpected system routing session created (request id="
+                            + requestId
+                            + "):"
+                            + sessionInfo);
+        }
+
+        if (mRemoteCallback == null) {
+            throw new IllegalStateException("Unexpected: remote callback is null.");
+        }
+
+        int routingTypes = 0;
+        var providerInfo = mProviderInfo;
+        for (String selectedRouteId : sessionInfo.getSelectedRoutes()) {
+            MediaRoute2Info route = providerInfo.mRoutes.get(selectedRouteId);
+            if (route == null) {
+                throw new IllegalArgumentException(
+                        "Invalid selected route with id: " + selectedRouteId);
+            }
+            routingTypes |= route.getSupportedRoutingTypes();
+        }
+
+        if ((routingTypes & MediaRoute2Info.FLAG_ROUTING_TYPE_SYSTEM_AUDIO) == 0) {
+            // TODO: b/380431086 - Populate video stream once we add support for video.
+            throw new IllegalArgumentException(
+                    "Selected routes for system media don't support any system media routing"
+                            + " types.");
+        }
+
+        AudioFormat audioFormat = formats.mAudioFormat;
+        var mediaStreamsBuilder = new MediaStreams.Builder();
+        if (audioFormat != null) {
+            populateAudioStream(audioFormat, uid, mediaStreamsBuilder);
+        }
+        // TODO: b/380431086 - Populate video stream once we add support for video.
+
+        MediaStreams streams = mediaStreamsBuilder.build();
+        var audioRecord = streams.mAudioRecord;
+        if (audioRecord == null) {
+            Log.e(
+                    TAG,
+                    "Audio record is not populated. Returning an empty stream and scheduling the"
+                            + " session release for: "
+                            + sessionInfo);
+            mHandler.post(() -> onReleaseSession(REQUEST_ID_NONE, sessionInfo.getOriginalId()));
+            notifyRequestFailed(requestId, REASON_FAILED_TO_REROUTE_SYSTEM_MEDIA);
+            return null;
+        }
+
+        synchronized (mSessionLock) {
+            try {
+                mRemoteCallback.notifySessionCreated(requestId, sessionInfo);
+            } catch (RemoteException ex) {
+                ex.rethrowFromSystemServer();
+            }
+            mOngoingMediaStreams.put(sessionInfo.getOriginalId(), streams);
+            return streams;
+        }
+    }
+
+    @RequiresPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
+    private void populateAudioStream(
+            AudioFormat audioFormat, int uid, MediaStreams.Builder builder) {
+        var audioAttributes =
+                new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
+        var audioMixingRuleBuilder =
+                new AudioMixingRule.Builder()
+                        .addRule(audioAttributes, AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE);
+        if (uid != Process.INVALID_UID) {
+            audioMixingRuleBuilder.addMixRule(AudioMixingRule.RULE_MATCH_UID, uid);
+        }
+
+        AudioMix mix =
+                new AudioMix.Builder(audioMixingRuleBuilder.build())
+                        .setFormat(audioFormat)
+                        .setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK)
+                        .build();
+        AudioPolicy audioPolicy =
+                new AudioPolicy.Builder(this).setLooper(mHandler.getLooper()).addMix(mix).build();
+        var audioManager = getSystemService(AudioManager.class);
+        if (audioManager == null) {
+            Log.e(TAG, "Couldn't fetch the audio manager.");
+            return;
+        }
+        audioManager.registerAudioPolicy(audioPolicy);
+        var audioRecord = audioPolicy.createAudioRecordSink(mix);
+        if (audioRecord == null) {
+            Log.e(TAG, "Audio record creation failed.");
+            audioManager.unregisterAudioPolicy(audioPolicy);
+            return;
+        }
+        builder.setAudioStream(audioPolicy, audioRecord);
     }
 
     /**
@@ -344,7 +486,7 @@
      * {@link RoutingSessionInfo#getSelectedRoutes() selected routes} are changed.
      */
     public final void notifySessionUpdated(@NonNull RoutingSessionInfo sessionInfo) {
-        Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+        requireNonNull(sessionInfo, "sessionInfo must not be null");
 
         if (DEBUG) {
             Log.d(TAG, "notifySessionUpdated: Updating session id=" + sessionInfo);
@@ -379,6 +521,7 @@
         RoutingSessionInfo sessionInfo;
         synchronized (mSessionLock) {
             sessionInfo = mSessionInfos.remove(sessionId);
+            maybeReleaseMediaStreams(sessionId);
 
             if (sessionInfo == null) {
                 Log.w(TAG, "notifySessionReleased: Ignoring unknown session info.");
@@ -396,6 +539,34 @@
         }
     }
 
+    /** Releases any system media routing resources associated with the given {@code sessionId}. */
+    private void maybeReleaseMediaStreams(String sessionId) {
+        if (!Flags.enableMirroringInMediaRouter2()) {
+            return;
+        }
+        synchronized (mSessionLock) {
+            var streams = mOngoingMediaStreams.remove(sessionId);
+            if (streams != null) {
+                releaseAudioStream(streams.mAudioPolicy, streams.mAudioRecord);
+                // TODO: b/380431086: Release the video stream once implemented.
+            }
+        }
+    }
+
+    // We cannot reach the code that requires MODIFY_AUDIO_ROUTING without holding it.
+    @SuppressWarnings("MissingPermission")
+    private void releaseAudioStream(AudioPolicy audioPolicy, AudioRecord audioRecord) {
+        if (audioPolicy == null) {
+            return;
+        }
+        var audioManager = getSystemService(AudioManager.class);
+        if (audioManager == null) {
+            return;
+        }
+        audioRecord.stop();
+        audioManager.unregisterAudioPolicy(audioPolicy);
+    }
+
     /**
      * Notifies to the client that the request has failed.
      *
@@ -569,7 +740,7 @@
      * Updates routes of the provider and notifies the system media router service.
      */
     public final void notifyRoutes(@NonNull Collection<MediaRoute2Info> routes) {
-        Objects.requireNonNull(routes, "routes must not be null");
+        requireNonNull(routes, "routes must not be null");
         List<MediaRoute2Info> sanitizedRoutes = new ArrayList<>(routes.size());
 
         for (MediaRoute2Info route : routes) {
@@ -763,6 +934,32 @@
         }
 
         @Override
+        public void requestCreateSystemMediaSession(
+                long requestId,
+                int uid,
+                String packageName,
+                String routeId,
+                @Nullable Bundle sessionHints) {
+            if (!checkCallerIsSystem()) {
+                return;
+            }
+            if (!checkRouteIdIsValid(routeId, "requestCreateSession")) {
+                return;
+            }
+            synchronized (mRequestIdsLock) {
+                mSystemMediaSessionCreationRequests.put(requestId, uid);
+            }
+            mHandler.sendMessage(
+                    obtainMessage(
+                            MediaRoute2ProviderService::onCreateSystemRoutingSession,
+                            MediaRoute2ProviderService.this,
+                            requestId,
+                            packageName,
+                            routeId,
+                            sessionHints));
+        }
+
+        @Override
         public void selectRoute(long requestId, String sessionId, String routeId) {
             if (!checkCallerIsSystem()) {
                 return;
@@ -825,6 +1022,10 @@
             if (!checkSessionIdIsValid(sessionId, "releaseSession")) {
                 return;
             }
+            // We proactively release the system media routing once the system requests it, to
+            // ensure it happens immediately.
+            maybeReleaseMediaStreams(sessionId);
+
             addRequestId(requestId);
             mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onReleaseSession,
                     MediaRoute2ProviderService.this, requestId, sessionId));
@@ -843,12 +1044,14 @@
     @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
     public static final class MediaStreams {
 
-        private final AudioRecord mAudioRecord;
+        @Nullable private final AudioPolicy mAudioPolicy;
+        @Nullable private final AudioRecord mAudioRecord;
 
         // TODO: b/380431086: Add the video equivalent.
 
-        private MediaStreams(AudioRecord mAudioRecord) {
-            this.mAudioRecord = mAudioRecord;
+        private MediaStreams(Builder builder) {
+            this.mAudioPolicy = builder.mAudioPolicy;
+            this.mAudioRecord = builder.mAudioRecord;
         }
 
         /**
@@ -859,8 +1062,33 @@
         public AudioRecord getAudioRecord() {
             return mAudioRecord;
         }
+
+        /**
+         * Builder for {@link MediaStreams}.
+         *
+         * @hide
+         */
+        public static final class Builder {
+
+            @Nullable private AudioPolicy mAudioPolicy;
+            @Nullable private AudioRecord mAudioRecord;
+
+            /** Populates system media audio-related structures. */
+            public Builder setAudioStream(
+                    @NonNull AudioPolicy audioPolicy, @NonNull AudioRecord audioRecord) {
+                mAudioPolicy = requireNonNull(audioPolicy);
+                mAudioRecord = requireNonNull(audioRecord);
+                return this;
+            }
+
+            /** Builds a {@link MediaStreams} instance. */
+            public MediaStreams build() {
+                return new MediaStreams(this);
+            }
+        }
     }
 
+
     /**
      * Holds the formats to encode media data to be read from {@link MediaStreams}.
      *
@@ -911,7 +1139,7 @@
              */
             @NonNull
             public Builder setAudioFormat(@NonNull AudioFormat audioFormat) {
-                this.mAudioFormat = Objects.requireNonNull(audioFormat);
+                this.mAudioFormat = requireNonNull(audioFormat);
                 return this;
             }
 
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 20108e7..3ac5de3 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -809,7 +809,7 @@
      * updates} in order to keep the system UI in a consistent state. You can also call this method
      * at any other point to update the listing preference dynamically.
      *
-     * <p>Any calls to this method from a privileged router will throw an {@link
+     * <p>Calling this method on a proxy router instance will throw an {@link
      * UnsupportedOperationException}.
      *
      * <p>Notes:
@@ -2675,7 +2675,7 @@
         @Override
         public void setRouteListingPreference(@Nullable RouteListingPreference preference) {
             throw new UnsupportedOperationException(
-                    "RouteListingPreference cannot be set by a privileged MediaRouter2 instance.");
+                    "RouteListingPreference cannot be set by a proxy MediaRouter2 instance.");
         }
 
         @Override
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index fc184fe..8419ce7 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -1149,9 +1149,9 @@
 
 static jobject getJavaResources(
         JNIEnv *env,
-        const std::vector<MediaCodec::InstanceResourceInfo>& resources) {
+        const std::vector<InstanceResourceInfo>& resources) {
     jobject resourcesObj = env->NewObject(gArrayListInfo.clazz, gArrayListInfo.ctorId);
-    for (const MediaCodec::InstanceResourceInfo& res : resources) {
+    for (const InstanceResourceInfo& res : resources) {
         ScopedLocalRef<jobject> object{env, env->NewObject(
                 gInstanceResourceInfo.clazz, gInstanceResourceInfo.ctorId)};
         ScopedLocalRef<jstring> nameStr{env, env->NewStringUTF(res.mName.c_str())};
@@ -1169,7 +1169,7 @@
 }
 
 status_t JMediaCodec::getRequiredResources(JNIEnv *env, jobject *resourcesObj) {
-    std::vector<MediaCodec::InstanceResourceInfo> resources;
+    std::vector<InstanceResourceInfo> resources;
     status_t status = mCodec->getRequiredResources(resources);
     if (status != OK) {
         return status;
@@ -3615,9 +3615,9 @@
 
 static jobject getJavaResources(
         JNIEnv *env,
-        const std::vector<MediaCodec::GlobalResourceInfo>& resources) {
+        const std::vector<GlobalResourceInfo>& resources) {
     jobject resourcesObj = env->NewObject(gArrayListInfo.clazz, gArrayListInfo.ctorId);
-    for (const MediaCodec::GlobalResourceInfo& res : resources) {
+    for (const GlobalResourceInfo& res : resources) {
         ScopedLocalRef<jobject> object{env, env->NewObject(
                 gGlobalResourceInfo.clazz, gGlobalResourceInfo.ctorId)};
         ScopedLocalRef<jstring> nameStr{env, env->NewStringUTF(res.mName.c_str())};
@@ -3633,7 +3633,7 @@
 static jobject android_media_MediaCodec_getGloballyAvailableResources(
         JNIEnv *env, jobject thiz) {
     (void)thiz;
-    std::vector<MediaCodec::GlobalResourceInfo> resources;
+    std::vector<GlobalResourceInfo> resources;
     status_t status = MediaCodec::getGloballyAvailableResources(resources);
     if (status != OK) {
         if (status == ERROR_UNSUPPORTED) {
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index 1945d90..9257901 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -22,6 +22,7 @@
 #include <aidl/android/hardware/power/SessionHint.h>
 #include <aidl/android/hardware/power/SessionMode.h>
 #include <aidl/android/hardware/power/SessionTag.h>
+#include <aidl/android/hardware/power/SupportInfo.h>
 #include <aidl/android/hardware/power/WorkDuration.h>
 #include <aidl/android/hardware/power/WorkDurationFixedV1.h>
 #include <aidl/android/os/IHintManager.h>
@@ -148,10 +149,36 @@
     std::future<bool> mChannelCreationFinished;
 };
 
+class SupportInfoWrapper {
+public:
+    SupportInfoWrapper(hal::SupportInfo& info);
+    bool isSessionModeSupported(hal::SessionMode mode);
+    bool isSessionHintSupported(hal::SessionHint hint);
+
+private:
+    template <class T>
+    bool getEnumSupportFromBitfield(T& enumValue, int64_t& supportBitfield) {
+        // extract the bit corresponding to the enum by shifting the bitfield
+        // over that much and cutting off any extra values
+        return (supportBitfield >> static_cast<int>(enumValue)) % 2;
+    }
+    hal::SupportInfo mSupportInfo;
+};
+
+class HintManagerClient : public IHintManager::BnHintManagerClient {
+public:
+    // Currently a no-op that exists for FMQ init to call in the future
+    ndk::ScopedAStatus receiveChannelConfig(const hal::ChannelConfig&) {
+        return ndk::ScopedAStatus::ok();
+    }
+};
+
 struct APerformanceHintManager {
 public:
     static APerformanceHintManager* getInstance();
-    APerformanceHintManager(std::shared_ptr<IHintManager>& service, int64_t preferredRateNanos);
+    APerformanceHintManager(std::shared_ptr<IHintManager>& service,
+                            IHintManager::HintManagerClientData&& clientData,
+                            std::shared_ptr<HintManagerClient> callbackClient);
     APerformanceHintManager() = delete;
     ~APerformanceHintManager();
 
@@ -169,29 +196,21 @@
     FMQWrapper& getFMQWrapper();
     bool canSendLoadHints(std::vector<hal::SessionHint>& hints, int64_t now) REQUIRES(sHintMutex);
     void initJava(JNIEnv* _Nonnull env);
-    ndk::ScopedAIBinder_Weak x;
     template <class T>
     static void layersFromNativeSurfaces(ANativeWindow** windows, int numWindows,
                                          ASurfaceControl** controls, int numSurfaceControls,
                                          std::vector<T>& out);
+    ndk::SpAIBinder& getToken();
+    SupportInfoWrapper& getSupportInfo();
 
 private:
-    // Necessary to create an empty binder object
-    static void* tokenStubOnCreate(void*) {
-        return nullptr;
-    }
-    static void tokenStubOnDestroy(void*) {}
-    static binder_status_t tokenStubOnTransact(AIBinder*, transaction_code_t, const AParcel*,
-                                               AParcel*) {
-        return STATUS_OK;
-    }
-
     static APerformanceHintManager* create(std::shared_ptr<IHintManager> iHintManager);
 
     std::shared_ptr<IHintManager> mHintManager;
+    std::shared_ptr<HintManagerClient> mCallbackClient;
+    IHintManager::HintManagerClientData mClientData;
+    SupportInfoWrapper mSupportInfoWrapper;
     ndk::SpAIBinder mToken;
-    const int64_t mPreferredRateNanos;
-    std::optional<int32_t> mMaxGraphicsPipelineThreadsCount;
     FMQWrapper mFMQWrapper;
     double mHintBudget = kMaxLoadHintsPerInterval;
     int64_t mLastBudgetReplenish = 0;
@@ -273,14 +292,27 @@
     return APerformanceHintManager::getInstance()->getFMQWrapper();
 }
 
+// ===================================== SupportInfoWrapper implementation
+
+SupportInfoWrapper::SupportInfoWrapper(hal::SupportInfo& info) : mSupportInfo(info) {}
+
+bool SupportInfoWrapper::isSessionHintSupported(hal::SessionHint hint) {
+    return getEnumSupportFromBitfield(hint, mSupportInfo.sessionHints);
+}
+
+bool SupportInfoWrapper::isSessionModeSupported(hal::SessionMode mode) {
+    return getEnumSupportFromBitfield(mode, mSupportInfo.sessionModes);
+}
+
 // ===================================== APerformanceHintManager implementation
 APerformanceHintManager::APerformanceHintManager(std::shared_ptr<IHintManager>& manager,
-                                                 int64_t preferredRateNanos)
-      : mHintManager(std::move(manager)), mPreferredRateNanos(preferredRateNanos) {
-    static AIBinder_Class* tokenBinderClass =
-            AIBinder_Class_define("phm_token", tokenStubOnCreate, tokenStubOnDestroy,
-                                  tokenStubOnTransact);
-    mToken = ndk::SpAIBinder(AIBinder_new(tokenBinderClass, nullptr));
+                                                 IHintManager::HintManagerClientData&& clientData,
+                                                 std::shared_ptr<HintManagerClient> callbackClient)
+      : mHintManager(std::move(manager)),
+        mCallbackClient(callbackClient),
+        mClientData(clientData),
+        mSupportInfoWrapper(clientData.supportInfo),
+        mToken(callbackClient->asBinder()) {
     if (mFMQWrapper.isSupported()) {
         mFMQWrapper.setToken(mToken);
         mFMQWrapper.startChannel(mHintManager.get());
@@ -315,16 +347,17 @@
         ALOGE("%s: PerformanceHint service is not ready ", __FUNCTION__);
         return nullptr;
     }
-    int64_t preferredRateNanos = -1L;
-    ndk::ScopedAStatus ret = manager->getHintSessionPreferredRate(&preferredRateNanos);
+    std::shared_ptr<HintManagerClient> client = ndk::SharedRefBase::make<HintManagerClient>();
+    IHintManager::HintManagerClientData clientData;
+    ndk::ScopedAStatus ret = manager->registerClient(client, &clientData);
     if (!ret.isOk()) {
-        ALOGE("%s: PerformanceHint cannot get preferred rate. %s", __FUNCTION__, ret.getMessage());
+        ALOGE("%s: PerformanceHint is not supported. %s", __FUNCTION__, ret.getMessage());
         return nullptr;
     }
-    if (preferredRateNanos <= 0) {
-        preferredRateNanos = -1L;
+    if (clientData.preferredRateNanos <= 0) {
+        clientData.preferredRateNanos = -1L;
     }
-    return new APerformanceHintManager(manager, preferredRateNanos);
+    return new APerformanceHintManager(manager, std::move(clientData), client);
 }
 
 bool APerformanceHintManager::canSendLoadHints(std::vector<hal::SessionHint>& hints, int64_t now) {
@@ -389,7 +422,9 @@
         ALOGE("%s: PerformanceHint cannot create session. %s", __FUNCTION__, ret.getMessage());
         return nullptr;
     }
-    auto out = new APerformanceHintSession(mHintManager, std::move(session), mPreferredRateNanos,
+
+    auto out = new APerformanceHintSession(mHintManager, std::move(session),
+                                           mClientData.preferredRateNanos,
                                            sessionCreationConfig->targetWorkDurationNanos, isJava,
                                            sessionConfig.id == -1
                                                    ? std::nullopt
@@ -416,24 +451,11 @@
 }
 
 int64_t APerformanceHintManager::getPreferredRateNanos() const {
-    return mPreferredRateNanos;
+    return mClientData.preferredRateNanos;
 }
 
 int32_t APerformanceHintManager::getMaxGraphicsPipelineThreadsCount() {
-    if (!mMaxGraphicsPipelineThreadsCount.has_value()) {
-        int32_t threadsCount = -1;
-        ndk::ScopedAStatus ret = mHintManager->getMaxGraphicsPipelineThreadsCount(&threadsCount);
-        if (!ret.isOk()) {
-            ALOGE("%s: PerformanceHint cannot get max graphics pipeline threads count. %s",
-                  __FUNCTION__, ret.getMessage());
-            return -1;
-        }
-        if (threadsCount <= 0) {
-            threadsCount = -1;
-        }
-        mMaxGraphicsPipelineThreadsCount.emplace(threadsCount);
-    }
-    return mMaxGraphicsPipelineThreadsCount.value();
+    return mClientData.maxGraphicsPipelineThreads;
 }
 
 FMQWrapper& APerformanceHintManager::getFMQWrapper() {
@@ -450,6 +472,14 @@
     mJavaInitialized = true;
 }
 
+ndk::SpAIBinder& APerformanceHintManager::getToken() {
+    return mToken;
+}
+
+SupportInfoWrapper& APerformanceHintManager::getSupportInfo() {
+    return mSupportInfoWrapper;
+}
+
 // ===================================== APerformanceHintSession implementation
 
 constexpr int kNumEnums = enum_size<hal::SessionHint>();
@@ -1170,7 +1200,7 @@
     if (!useNewLoadHintBehavior()) {
         return ENOTSUP;
     }
-    return session->notifyWorkloadReset(cpu, gpu, debugName);
+    return session->notifyWorkloadSpike(cpu, gpu, debugName);
 }
 
 int APerformanceHint_setNativeSurfaces(APerformanceHintSession* session,
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index c166e73..e3c10f6 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -56,9 +56,6 @@
                  const SessionCreationConfig& creationConfig, hal::SessionConfig* config,
                  std::shared_ptr<IHintSession>* _aidl_return),
                 (override));
-    MOCK_METHOD(ScopedAStatus, getHintSessionPreferredRate, (int64_t * _aidl_return), (override));
-    MOCK_METHOD(ScopedAStatus, getMaxGraphicsPipelineThreadsCount, (int32_t* _aidl_return),
-                (override));
     MOCK_METHOD(ScopedAStatus, setHintSessionThreads,
                 (const std::shared_ptr<IHintSession>& hintSession,
                  const ::std::vector<int32_t>& tids),
@@ -84,6 +81,11 @@
     MOCK_METHOD(ScopedAStatus, getGpuHeadroomMinIntervalMillis, (int64_t* _aidl_return),
                 (override));
     MOCK_METHOD(ScopedAStatus, passSessionManagerBinder, (const SpAIBinder& sessionManager));
+    MOCK_METHOD(ScopedAStatus, registerClient,
+                (const std::shared_ptr<::aidl::android::os::IHintManager::IHintManagerClient>&
+                         clientDataIn,
+                 ::aidl::android::os::IHintManager::HintManagerClientData* _aidl_return),
+                (override));
     MOCK_METHOD(SpAIBinder, asBinder, (), (override));
     MOCK_METHOD(bool, isRemote, (), (override));
 };
@@ -125,10 +127,9 @@
 
     APerformanceHintManager* createManager() {
         APerformanceHint_setUseFMQForTesting(mUsingFMQ);
-        ON_CALL(*mMockIHintManager, getHintSessionPreferredRate(_))
-                .WillByDefault(DoAll(SetArgPointee<0>(123L), [] { return ScopedAStatus::ok(); }));
-        ON_CALL(*mMockIHintManager, getMaxGraphicsPipelineThreadsCount(_))
-                .WillByDefault(DoAll(SetArgPointee<0>(5), [] { return ScopedAStatus::ok(); }));
+        ON_CALL(*mMockIHintManager, registerClient(_, _))
+                .WillByDefault(
+                        DoAll(SetArgPointee<1>(mClientData), [] { return ScopedAStatus::ok(); }));
         return APerformanceHint_getManager();
     }
 
@@ -238,6 +239,20 @@
     int kMockQueueSize = 20;
     bool mUsingFMQ = false;
 
+    IHintManager::HintManagerClientData mClientData{
+            .powerHalVersion = 6,
+            .maxGraphicsPipelineThreads = 5,
+            .preferredRateNanos = 123L,
+            .supportInfo{
+                    .usesSessions = true,
+                    .boosts = 0,
+                    .modes = 0,
+                    .sessionHints = -1,
+                    .sessionModes = -1,
+                    .sessionTags = -1,
+            },
+    };
+
     int32_t mMaxLoadHintsPerInterval;
     int64_t mLoadHintInterval;
 
@@ -256,12 +271,6 @@
             lhs.gpuDurationNanos == rhs.gpuDurationNanos && lhs.durationNanos == rhs.durationNanos;
 }
 
-TEST_F(PerformanceHintTest, TestGetPreferredUpdateRateNanos) {
-    APerformanceHintManager* manager = createManager();
-    int64_t preferredUpdateRateNanos = APerformanceHint_getPreferredUpdateRateNanos(manager);
-    EXPECT_EQ(123L, preferredUpdateRateNanos);
-}
-
 TEST_F(PerformanceHintTest, TestSession) {
     APerformanceHintManager* manager = createManager();
     APerformanceHintSession* session = createSession(manager);
diff --git a/nfc/Android.bp b/nfc/Android.bp
index 7ad8c4c..b82dec8 100644
--- a/nfc/Android.bp
+++ b/nfc/Android.bp
@@ -37,6 +37,7 @@
 java_sdk_library {
     name: "framework-nfc",
     libs: [
+        "androidx.annotation_annotation",
         "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
         "framework-permission-s.stubs.module_lib",
         "framework-permission.stubs.module_lib",
@@ -70,6 +71,7 @@
         "//cts/hostsidetests/multidevices/nfc:__subpackages__",
         "//cts/tests/tests/nfc",
         "//packages/apps/Nfc:__subpackages__",
+        "//packages/modules/Nfc:__subpackages__",
     ],
     jarjar_rules: ":nfc-jarjar-rules",
     lint: {
diff --git a/nfc/OWNERS b/nfc/OWNERS
index 35e9713..f46dccd 100644
--- a/nfc/OWNERS
+++ b/nfc/OWNERS
@@ -1,2 +1,2 @@
 # Bug component: 48448
-include platform/packages/apps/Nfc:/OWNERS
+include platform/packages/apps/Nfc:/OWNERS
\ No newline at end of file
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index e97b15d..6bd6072 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -85,6 +85,10 @@
     field public static final int HCE_ACTIVATE = 1; // 0x1
     field public static final int HCE_DATA_TRANSFERRED = 2; // 0x2
     field public static final int HCE_DEACTIVATE = 3; // 0x3
+    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_A = 1; // 0x1
+    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_B = 2; // 0x2
+    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_F = 4; // 0x4
+    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_NONE = 0; // 0x0
     field public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2; // 0x2
     field public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1; // 0x1
     field public static final int STATUS_OK = 0; // 0x0
@@ -196,9 +200,11 @@
     method @Nullable @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public android.nfc.T4tNdefNfceeCcFileInfo readCcfile();
     method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public byte[] readData(@IntRange(from=0, to=65535) int);
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public int writeData(@IntRange(from=0, to=65535) int, @NonNull byte[]);
+    field public static final int CLEAR_DATA_FAILED_DEVICE_BUSY = -1; // 0xffffffff
     field public static final int CLEAR_DATA_FAILED_INTERNAL = 0; // 0x0
     field public static final int CLEAR_DATA_SUCCESS = 1; // 0x1
     field public static final int WRITE_DATA_ERROR_CONNECTION_FAILED = -6; // 0xfffffffa
+    field public static final int WRITE_DATA_ERROR_DEVICE_BUSY = -9; // 0xfffffff7
     field public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7; // 0xfffffff9
     field public static final int WRITE_DATA_ERROR_INTERNAL = -1; // 0xffffffff
     field public static final int WRITE_DATA_ERROR_INVALID_FILE_ID = -4; // 0xfffffffc
@@ -213,21 +219,14 @@
     method public int describeContents();
     method @IntRange(from=15, to=32767) public int getCcFileLength();
     method @IntRange(from=0xffffffff, to=65535) public int getFileId();
-    method @IntRange(from=15, to=65535) public int getMaxReadLength();
     method @IntRange(from=5, to=32767) public int getMaxSize();
-    method @IntRange(from=13, to=65535) public int getMaxWriteLength();
-    method public int getReadAccess();
     method public int getVersion();
-    method public int getWriteAccess();
+    method public boolean isReadAllowed();
+    method public boolean isWriteAllowed();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.nfc.T4tNdefNfceeCcFileInfo> CREATOR;
-    field public static final int READ_ACCESS_GRANTED_RESTRICTED = 128; // 0x80
-    field public static final int READ_ACCESS_GRANTED_UNRESTRICTED = 0; // 0x0
     field public static final int VERSION_2_0 = 32; // 0x20
     field public static final int VERSION_3_0 = 48; // 0x30
-    field public static final int WRITE_ACCESS_GRANTED_RESTRICTED = 128; // 0x80
-    field public static final int WRITE_ACCESS_GRANTED_UNRESTRICTED = 0; // 0x0
-    field public static final int WRITE_ACCESS_NOT_GRANTED = 255; // 0xff
   }
 
 }
@@ -250,6 +249,7 @@
     field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID = 1; // 0x1
     field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3; // 0x3
     field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_SUCCESS = 0; // 0x0
+    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_UNKNOWN = -1; // 0xffffffff
   }
 
 }
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index fb11875..b46e343 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -150,28 +150,24 @@
 
     /**
      * Technology Type for {@link #getActiveNfceeList()}.
-     * @hide
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     public static final int NFCEE_TECH_NONE = 0;
 
     /**
      * Technology Type for {@link #getActiveNfceeList()}.
-     * @hide
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     public static final int NFCEE_TECH_A = 1;
 
     /**
      * Technology Type for {@link #getActiveNfceeList()}.
-     * @hide
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     public static final int NFCEE_TECH_B = 1 << 1;
 
     /**
      * Technology Type for {@link #getActiveNfceeList()}.
-     * @hide
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     public static final int NFCEE_TECH_F = 1 << 2;
@@ -670,12 +666,15 @@
     /**
      * Get the Active NFCEE (NFC Execution Environment) List
      *
-     * @see Reader#getName() for the list of possible NFCEE names.
-     *
      * @return Map< String, @NfceeTechnology Integer >
      *         A HashMap where keys are activated secure elements and
-     *         the values are bitmap of technologies supported by each secure element
-     *         on success keys can contain "eSE" and "UICC", otherwise empty map.
+     *         the values are bitmap of technologies supported by each secure element:
+     *          NFCEE_TECH_A == 0x1
+     *          NFCEE_TECH_B == 0x2
+     *          NFCEE_TECH_F == 0x4
+     *         and keys can contain "eSE" and "SIM" with a number,
+     *         in case of failure an empty map is returned.
+     *         @see Reader#getName() for the list of possible NFCEE names.
      */
     @NonNull
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
diff --git a/nfc/java/android/nfc/T4tNdefNfcee.java b/nfc/java/android/nfc/T4tNdefNfcee.java
index 06d02c5..05a30aa 100644
--- a/nfc/java/android/nfc/T4tNdefNfcee.java
+++ b/nfc/java/android/nfc/T4tNdefNfcee.java
@@ -100,9 +100,14 @@
     public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7;
     /**
      * Returns flag for {@link #writeData(int, byte[])}.
-     * It idicates write data fail due to invalid ndef format.
+     * It indicates write data fail due to invalid ndef format.
      */
     public static final int WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED = -8;
+    /**
+     * Returns flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail if a concurrent NDEF NFCEE operation is ongoing.
+     */
+    public static final int WRITE_DATA_ERROR_DEVICE_BUSY = -9;
 
     /**
      * Possible return values for {@link #writeData(int, byte[])}.
@@ -119,6 +124,7 @@
         WRITE_DATA_ERROR_CONNECTION_FAILED,
         WRITE_DATA_ERROR_EMPTY_PAYLOAD,
         WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED,
+        WRITE_DATA_ERROR_DEVICE_BUSY,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface WriteDataStatus{}
@@ -128,6 +134,9 @@
      *
      * <p>This is an I/O operation and will block until complete. It must
      * not be called from the main application thread.</p>
+     * <p>Applications must send complete Ndef Message payload, do not need to fragment
+     * the payload, it will be automatically fragmented and defragmented by
+     * {@link #writeData} if it exceeds max message length limits</p>
      *
      * @param fileId File id (Refer NFC Forum Type 4 Tag Specification
      *               Section 4.2 File Identifiers and Access Conditions
@@ -155,9 +164,10 @@
      * @param fileId File Id (Refer
      *               Section 4.2 File Identifiers and Access Conditions
      *               for more information) from which to read.
-     * @return - Returns Ndef message if success
+     * @return - Returns complete Ndef message if success
      *           Refer to Nfc forum NDEF specification NDEF Message section
-     * @throws IllegalStateException if read fails because the fileId is invalid.
+     * @throws IllegalStateException if read fails because the fileId is invalid
+     *         or if a concurrent operation is in progress.
      * @hide
      */
     @SystemApi
@@ -179,6 +189,12 @@
      * It indicates clear data failed due to internal error while processing the clear.
      */
     public static final int CLEAR_DATA_FAILED_INTERNAL = 0;
+    /**
+     * Return flag for {@link #clearNdefData()}.
+     * It indicates clear data failed  if a concurrent NDEF NFCEE operation is ongoing.
+     */
+    public static final int CLEAR_DATA_FAILED_DEVICE_BUSY = -1;
+
 
     /**
      * Possible return values for {@link #clearNdefData()}.
@@ -188,6 +204,7 @@
     @IntDef(prefix = { "CLEAR_DATA_" }, value = {
         CLEAR_DATA_SUCCESS,
         CLEAR_DATA_FAILED_INTERNAL,
+        CLEAR_DATA_FAILED_DEVICE_BUSY,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ClearDataStatus{}
@@ -245,6 +262,7 @@
      * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
      *
      * @return Returns CC file content if success or null if failed to read.
+     * @throws IllegalStateException if the device is busy.
      * @hide
      */
     @SystemApi
diff --git a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
index 5fca052..ce67f8f 100644
--- a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
+++ b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
@@ -47,14 +47,6 @@
      */
     private int mVersion;
     /**
-     * Indicates the max data size by a single ReadBinary<p>
-     */
-    private int mMaxReadLength;
-    /**
-     * Indicates the max data size by a single UpdateBinary<p>
-     */
-    private int mMaxWriteLength;
-    /**
      * Indicates the NDEF File Identifier<p>
      */
     private int mFileId;
@@ -65,40 +57,35 @@
     /**
      * Indicates the read access condition<p>
      */
-    private int mReadAccess;
+    private boolean mIsReadAllowed;
     /**
      * Indicates the write access condition<p>
      */
-    private int mWriteAccess;
+    private boolean mIsWriteAllowed;
 
     /**
      * Constructor to be used by NFC service and internal classes.
      * @hide
      */
-    public T4tNdefNfceeCcFileInfo(int cclen, int version, int maxLe, int maxLc,
+    public T4tNdefNfceeCcFileInfo(int cclen, int version,
                       int ndefFileId, int ndefMaxSize,
-                      int ndefReadAccess, int ndefWriteAccess) {
+                      boolean isReadAllowed, boolean isWriteAllowed) {
         mCcLength = cclen;
         mVersion = version;
-        mMaxWriteLength = maxLc;
-        mMaxReadLength = maxLe;
         mFileId = ndefFileId;
         mMaxSize = ndefMaxSize;
-        mReadAccess = ndefReadAccess;
-        mWriteAccess = ndefWriteAccess;
+        mIsReadAllowed = isReadAllowed;
+        mIsWriteAllowed = isWriteAllowed;
     }
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-
         dest.writeInt(mCcLength);
         dest.writeInt(mVersion);
-        dest.writeInt(mMaxWriteLength);
-        dest.writeInt(mMaxReadLength);
         dest.writeInt(mFileId);
         dest.writeInt(mMaxSize);
-        dest.writeInt(mReadAccess);
-        dest.writeInt(mWriteAccess);
+        dest.writeBoolean(mIsReadAllowed);
+        dest.writeBoolean(mIsWriteAllowed);
     }
 
     /**
@@ -146,30 +133,6 @@
     }
 
     /**
-     * Indicates the max data size that can be read by a single invocation of
-     * {@link T4tNdefNfcee#readData(int)}.
-     *
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" MLe.
-     * @return max size of read (in bytes).
-     */
-    @IntRange(from = 0xf, to = 0xffff)
-    public int getMaxReadLength() {
-        return mMaxReadLength;
-    }
-
-    /**
-     * Indicates the max data size that can be written by a single invocation of
-     * {@link T4tNdefNfcee#writeData(int, byte[])}
-     *
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" MLc.
-     * @return max size of write (in bytes).
-     */
-    @IntRange(from = 0xd, to = 0xffff)
-    public int getMaxWriteLength() {
-        return mMaxWriteLength;
-    }
-
-    /**
      * Indicates the NDEF File Identifier. This is the identifier used in the last invocation of
      * {@link T4tNdefNfcee#writeData(int, byte[])}
      *
@@ -191,73 +154,21 @@
     }
 
     /**
-     * T4T tag read access granted without any security.
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
-     */
-    public static final int READ_ACCESS_GRANTED_UNRESTRICTED = 0x0;
-    /**
-     * T4T tag read access granted with limited proprietary access only.
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
-     */
-    public static final int READ_ACCESS_GRANTED_RESTRICTED = 0x80;
-
-    /**
-     * Possible return values for {@link #getVersion()}.
-     * @hide
-     */
-    @IntDef(prefix = { "READ_ACCESS_GRANTED_" }, value = {
-            READ_ACCESS_GRANTED_RESTRICTED,
-            READ_ACCESS_GRANTED_UNRESTRICTED,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ReadAccess {}
-
-    /**
      * Indicates the read access condition.
      * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
-     * @return read access restriction
+     * @return boolean true if read access is allowed, otherwise false.
      */
-    @ReadAccess
-    public int getReadAccess() {
-        return mReadAccess;
+    public boolean isReadAllowed() {
+        return mIsReadAllowed;
     }
 
     /**
-     * T4T tag write access granted without any security.
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
-     */
-    public static final int WRITE_ACCESS_GRANTED_UNRESTRICTED = 0x0;
-    /**
-     * T4T tag write access granted with limited proprietary access only.
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
-     */
-    public static final int WRITE_ACCESS_GRANTED_RESTRICTED = 0x80;
-    /**
-     * T4T tag write access not granted.
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
-     */
-    public static final int WRITE_ACCESS_NOT_GRANTED = 0xFF;
-
-    /**
-     * Possible return values for {@link #getVersion()}.
-     * @hide
-     */
-    @IntDef(prefix = { "READ_ACCESS_GRANTED_" }, value = {
-            WRITE_ACCESS_GRANTED_RESTRICTED,
-            WRITE_ACCESS_GRANTED_UNRESTRICTED,
-            WRITE_ACCESS_NOT_GRANTED,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface WriteAccess {}
-
-    /**
      * Indicates the write access condition.
      * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
-     * @return write access restriction
+     * @return boolean if write access is allowed, otherwise false.
      */
-    @WriteAccess
-    public int getWriteAccess() {
-        return mWriteAccess;
+    public boolean isWriteAllowed() {
+        return mIsWriteAllowed;
     }
 
     @Override
@@ -273,16 +184,14 @@
                     // NdefNfceeCcFileInfo fields
                     int cclen = in.readInt();
                     int version = in.readInt();
-                    int maxLe = in.readInt();
-                    int maxLc = in.readInt();
                     int ndefFileId = in.readInt();
                     int ndefMaxSize = in.readInt();
-                    int ndefReadAccess = in.readInt();
-                    int ndefWriteAccess = in.readInt();
+                    boolean isReadAllowed = in.readBoolean();
+                    boolean isWriteAllowed = in.readBoolean();
 
-                    return new T4tNdefNfceeCcFileInfo(cclen, version, maxLe, maxLc,
+                    return new T4tNdefNfceeCcFileInfo(cclen, version,
                             ndefFileId, ndefMaxSize,
-                            ndefReadAccess, ndefWriteAccess);
+                            isReadAllowed, isWriteAllowed);
                 }
 
                 @Override
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
index 8037702..e0bc15f 100644
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java
@@ -1114,6 +1114,14 @@
     @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
     public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3;
 
+    /**
+     * Setting the default subscription ID failed because of unknown error.
+     * @hide
+     */
+    @SystemApi
+    @FlaggedApi(Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+    public static final int SET_SUBSCRIPTION_ID_STATUS_UNKNOWN = -1;
+
     /** @hide */
     @IntDef(prefix = "SET_SUBSCRIPTION_ID_STATUS_",
             value = {
@@ -1121,6 +1129,7 @@
                     SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID,
                     SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR,
                     SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED,
+                    SET_SUBSCRIPTION_ID_STATUS_UNKNOWN
             })
     @Retention(RetentionPolicy.SOURCE)
     public @interface SetSubscriptionIdStatus {}
@@ -1129,9 +1138,10 @@
      * Sets the system's default NFC subscription id.
      *
      * <p> For devices with multiple UICC/EUICC that is configured to be NFCEE, this sets the
-     * default UICC NFCEE that will handle NFC offhost CE transactoions </p>
+     * default UICC NFCEE that will handle NFC offhost CE transactions </p>
      *
-     * @param subscriptionId the default NFC subscription Id to set.
+     * @param subscriptionId the default NFC subscription Id to set. User can get subscription id
+     *                       from {@link SubscriptionManager#getSubscriptionId(int)}
      * @return status of the operation.
      *
      * @throws UnsupportedOperationException If the device does not have
@@ -1153,7 +1163,7 @@
      * Returns the system's default NFC subscription id.
      *
      * <p> For devices with multiple UICC/EUICC that is configured to be NFCEE, this returns the
-     * default UICC NFCEE that will handle NFC offhost CE transactoions </p>
+     * default UICC NFCEE that will handle NFC offhost CE transactions </p>
      * <p> If the device has no UICC that can serve as NFCEE, this will return
      * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.</p>
      *
diff --git a/nfc/java/android/nfc/cardemulation/HostApduService.java b/nfc/java/android/nfc/cardemulation/HostApduService.java
index db1f6a2..fbf2203 100644
--- a/nfc/java/android/nfc/cardemulation/HostApduService.java
+++ b/nfc/java/android/nfc/cardemulation/HostApduService.java
@@ -289,7 +289,7 @@
                         try {
                             mNfcService.send(responseMsg);
                         } catch (RemoteException e) {
-                            Log.e("TAG", "Response not sent; RemoteException calling into " +
+                            Log.e(TAG, "Response not sent; RemoteException calling into " +
                                     "NfcService.");
                         }
                     }
diff --git a/nfc/java/android/nfc/cardemulation/OWNERS b/nfc/java/android/nfc/cardemulation/OWNERS
deleted file mode 100644
index 35e9713..0000000
--- a/nfc/java/android/nfc/cardemulation/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48448
-include platform/packages/apps/Nfc:/OWNERS
diff --git a/nfc/java/android/nfc/dta/OWNERS b/nfc/java/android/nfc/dta/OWNERS
deleted file mode 100644
index 35e9713..0000000
--- a/nfc/java/android/nfc/dta/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48448
-include platform/packages/apps/Nfc:/OWNERS
diff --git a/nfc/java/android/nfc/tech/OWNERS b/nfc/java/android/nfc/tech/OWNERS
deleted file mode 100644
index 35e9713..0000000
--- a/nfc/java/android/nfc/tech/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48448
-include platform/packages/apps/Nfc:/OWNERS
diff --git a/nfc/tests/Android.bp b/nfc/tests/Android.bp
index bfa814d..b6090e8 100644
--- a/nfc/tests/Android.bp
+++ b/nfc/tests/Android.bp
@@ -25,17 +25,36 @@
 android_test {
     name: "NfcManagerTests",
     static_libs: [
-        "androidx.test.ext.junit",
+        "androidx.test.core",
         "androidx.test.rules",
-        "mockito-target-minus-junit4",
+        "androidx.test.runner",
+        "androidx.test.ext.junit",
+        "framework-nfc.impl",
+        "mockito-target-extended-minus-junit4",
+        "frameworks-base-testutils",
         "truth",
+        "androidx.annotation_annotation",
+        "androidx.appcompat_appcompat",
+        "flag-junit",
+        "platform-test-annotations",
+        "testables",
     ],
     libs: [
-        "framework-nfc.impl",
+        "android.test.base.stubs.system",
+        "android.test.mock.stubs.system",
         "android.test.runner.stubs.system",
     ],
+    jni_libs: [
+        // Required for ExtendedMockito
+        "libdexmakerjvmtiagent",
+        "libstaticjvmtiagent",
+    ],
     srcs: ["src/**/*.java"],
     platform_apis: true,
     certificate: "platform",
-    test_suites: ["device-tests"],
+    test_suites: [
+        "device-tests",
+        "mts-nfc",
+    ],
+    min_sdk_version: "35", // Should be 36 later.
 }
diff --git a/nfc/tests/AndroidManifest.xml b/nfc/tests/AndroidManifest.xml
index 99e2c34c..9564672 100644
--- a/nfc/tests/AndroidManifest.xml
+++ b/nfc/tests/AndroidManifest.xml
@@ -17,7 +17,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.nfc">
 
-    <application>
+    <application android:debuggable="true">
         <uses-library android:name="android.test.runner" />
     </application>
 
diff --git a/nfc/tests/src/android/nfc/cardemulation/AidGroupTest.java b/nfc/tests/src/android/nfc/cardemulation/AidGroupTest.java
new file mode 100644
index 0000000..7e00102
--- /dev/null
+++ b/nfc/tests/src/android/nfc/cardemulation/AidGroupTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.cardemulation;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.os.Parcel;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AidGroupTest {
+    private AidGroup mAidGroup;
+
+    @Before
+    public void setUp() {
+        List<String> aids = new ArrayList<>();
+        aids.add("A0000000031010");
+        aids.add("A0000000041010");
+        aids.add("A0000000034710");
+        aids.add("A000000300");
+        mAidGroup = new AidGroup(aids, "payment");
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void testGetCategory() {
+        String category = mAidGroup.getCategory();
+        assertThat(category).isNotNull();
+        assertThat(category).isEqualTo("payment");
+    }
+
+    @Test
+    public void testGetAids() {
+        List<String> aids = mAidGroup.getAids();
+        assertThat(aids).isNotNull();
+        assertThat(aids.size()).isGreaterThan(0);
+        assertThat(aids.get(0)).isEqualTo("A0000000031010");
+    }
+
+    @Test
+    public void testWriteAsXml() throws IOException {
+        XmlSerializer out = mock(XmlSerializer.class);
+        mAidGroup.writeAsXml(out);
+        verify(out, atLeastOnce()).startTag(isNull(), anyString());
+        verify(out, atLeastOnce()).attribute(isNull(), anyString(), anyString());
+        verify(out, atLeastOnce()).endTag(isNull(), anyString());
+    }
+
+    @Test
+    public void testRightToParcel() {
+        Parcel parcel = mock(Parcel.class);
+        mAidGroup.writeToParcel(parcel, 0);
+        verify(parcel).writeString8(anyString());
+        verify(parcel).writeInt(anyInt());
+        verify(parcel).writeStringList(any());
+    }
+}
diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml
index b266912..2a6d68d 100644
--- a/packages/CompanionDeviceManager/res/values/strings.xml
+++ b/packages/CompanionDeviceManager/res/values/strings.xml
@@ -88,6 +88,17 @@
     <!-- Description of the helper dialog for NEARBY_DEVICE_STREAMING profile. [CHAR LIMIT=NONE] -->
     <string name="helper_summary_nearby_device_streaming"><xliff:g id="app_name" example="Exo">%1$s</xliff:g> is requesting permission on behalf of <xliff:g id="device_name" example="Chromebook">%2$s</xliff:g> to stream apps from your <xliff:g id="device_type" example="phone">%3$s</xliff:g></string>
 
+    <!-- ================= DEVICE_PROFILE_SENSOR_DEVICE_STREAMING ================= -->
+
+    <!-- Confirmation for associating an application with a companion device of SENSOR_DEVICE_STREAMING profile (type) [CHAR LIMIT=NONE] -->
+    <string name="title_sensor_device_streaming">Allow &lt;strong&gt;<xliff:g id="app_name" example="Exo">%1$s</xliff:g>&lt;/strong&gt; to stream audio and system features between your <xliff:g id="device_type" example="phone">%2$s</xliff:g> and &lt;strong&gt;<xliff:g id="device_name" example="Chromebook">%3$s</xliff:g>&lt;/strong&gt;?</string>
+
+    <!-- Summary for associating an application with a companion device of SENSOR_DEVICE_STREAMING profile [CHAR LIMIT=NONE] -->
+    <string name="summary_sensor_device_streaming"><xliff:g id="app_name" example="Exo">%1$s</xliff:g> will have access to anything that’s played on your <xliff:g id="device_name" example="Chromebook">%3$s</xliff:g>.&lt;br/>&lt;br/><xliff:g id="app_name" example="Exo">%1$s</xliff:g> will be able to stream audio to <xliff:g id="device_name" example="Chromebook">%3$s</xliff:g> until you remove access to this permission.</string>
+
+    <!-- Description of the helper dialog for SENSOR_DEVICE_STREAMING profile. [CHAR LIMIT=NONE] -->
+    <string name="helper_summary_sensor_device_streaming"><xliff:g id="app_name" example="Exo">%1$s</xliff:g> is requesting permission on behalf of <xliff:g id="device_name" example="Chromebook">%2$s</xliff:g> to stream audio and system features between your devices.</string>
+
     <!-- ================= null profile ================= -->
 
     <!-- A noun for a companion device with unspecified profile (type) [CHAR LIMIT=30] -->
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceResources.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceResources.java
index 37b1f29..fd77164 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceResources.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceResources.java
@@ -21,6 +21,7 @@
 import static android.companion.AssociationRequest.DEVICE_PROFILE_COMPUTER;
 import static android.companion.AssociationRequest.DEVICE_PROFILE_GLASSES;
 import static android.companion.AssociationRequest.DEVICE_PROFILE_NEARBY_DEVICE_STREAMING;
+import static android.companion.AssociationRequest.DEVICE_PROFILE_SENSOR_DEVICE_STREAMING;
 import static android.companion.AssociationRequest.DEVICE_PROFILE_WATCH;
 import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
 
@@ -116,6 +117,7 @@
         map.put(DEVICE_PROFILE_AUTOMOTIVE_PROJECTION, R.string.title_automotive_projection);
         map.put(DEVICE_PROFILE_COMPUTER, R.string.title_computer);
         map.put(DEVICE_PROFILE_NEARBY_DEVICE_STREAMING, R.string.title_nearby_device_streaming);
+        map.put(DEVICE_PROFILE_SENSOR_DEVICE_STREAMING, R.string.title_sensor_device_streaming);
         map.put(DEVICE_PROFILE_WATCH, R.string.confirmation_title);
         map.put(DEVICE_PROFILE_GLASSES, R.string.confirmation_title_glasses);
         map.put(null, R.string.confirmation_title);
@@ -130,6 +132,7 @@
         map.put(DEVICE_PROFILE_GLASSES, R.string.summary_glasses);
         map.put(DEVICE_PROFILE_APP_STREAMING, R.string.summary_app_streaming);
         map.put(DEVICE_PROFILE_NEARBY_DEVICE_STREAMING, R.string.summary_nearby_device_streaming);
+        map.put(DEVICE_PROFILE_SENSOR_DEVICE_STREAMING, R.string.summary_sensor_device_streaming);
         map.put(null, R.string.summary_generic);
 
         PROFILE_SUMMARIES = unmodifiableMap(map);
@@ -141,6 +144,8 @@
         map.put(DEVICE_PROFILE_APP_STREAMING, R.string.helper_summary_app_streaming);
         map.put(DEVICE_PROFILE_NEARBY_DEVICE_STREAMING,
                 R.string.helper_summary_nearby_device_streaming);
+        map.put(DEVICE_PROFILE_SENSOR_DEVICE_STREAMING,
+                R.string.helper_summary_sensor_device_streaming);
         map.put(DEVICE_PROFILE_COMPUTER, R.string.helper_summary_computer);
 
         PROFILE_HELPER_SUMMARIES = unmodifiableMap(map);
@@ -204,6 +209,7 @@
         set.add(DEVICE_PROFILE_COMPUTER);
         set.add(DEVICE_PROFILE_AUTOMOTIVE_PROJECTION);
         set.add(DEVICE_PROFILE_NEARBY_DEVICE_STREAMING);
+        set.add(DEVICE_PROFILE_SENSOR_DEVICE_STREAMING);
         set.add(null);
 
         SUPPORTED_SELF_MANAGED_PROFILES = unmodifiableSet(set);
diff --git a/packages/CrashRecovery/framework/Android.bp b/packages/CrashRecovery/framework/Android.bp
index 43d8a62..1a3446ec 100644
--- a/packages/CrashRecovery/framework/Android.bp
+++ b/packages/CrashRecovery/framework/Android.bp
@@ -14,7 +14,11 @@
     name: "framework-platformcrashrecovery",
     srcs: [":framework-crashrecovery-sources"],
     defaults: ["framework-non-updatable-unbundled-defaults"],
-    permitted_packages: ["android.service.watchdog"],
+    permitted_packages: [
+        "android.service.watchdog",
+        "android.crashrecovery",
+    ],
+    static_libs: ["android.crashrecovery.flags-aconfig-java"],
     aidl: {
         include_dirs: [
             "frameworks/base/core/java",
diff --git a/packages/CrashRecovery/framework/api/system-current.txt b/packages/CrashRecovery/framework/api/system-current.txt
index 3a48a4a..68429ea 100644
--- a/packages/CrashRecovery/framework/api/system-current.txt
+++ b/packages/CrashRecovery/framework/api/system-current.txt
@@ -9,7 +9,9 @@
     method @NonNull public abstract java.util.List<java.lang.String> onGetRequestedPackages();
     method @NonNull public abstract java.util.List<android.service.watchdog.ExplicitHealthCheckService.PackageConfig> onGetSupportedPackages();
     method public abstract void onRequestHealthCheck(@NonNull String);
+    method @FlaggedApi("android.crashrecovery.flags.enable_crashrecovery") public final void setHealthCheckResultCallback(@Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<android.os.Bundle>);
     field public static final String BIND_PERMISSION = "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE";
+    field @FlaggedApi("android.crashrecovery.flags.enable_crashrecovery") public static final String EXTRA_HEALTH_CHECK_PASSED_PACKAGE = "android.service.watchdog.extra.HEALTH_CHECK_PASSED_PACKAGE";
     field public static final String SERVICE_INTERFACE = "android.service.watchdog.ExplicitHealthCheckService";
   }
 
diff --git a/packages/CrashRecovery/framework/api/test-current.txt b/packages/CrashRecovery/framework/api/test-current.txt
index 54f501f..d802177 100644
--- a/packages/CrashRecovery/framework/api/test-current.txt
+++ b/packages/CrashRecovery/framework/api/test-current.txt
@@ -1,9 +1 @@
 // Signature format: 2.0
-package android.service.watchdog {
-
-  public abstract class ExplicitHealthCheckService extends android.app.Service {
-    method public void setCallback(@Nullable android.os.RemoteCallback);
-  }
-
-}
-
diff --git a/packages/CrashRecovery/framework/java/android/service/watchdog/ExplicitHealthCheckService.java b/packages/CrashRecovery/framework/java/android/service/watchdog/ExplicitHealthCheckService.java
index 7befbfb..b03e376 100644
--- a/packages/CrashRecovery/framework/java/android/service/watchdog/ExplicitHealthCheckService.java
+++ b/packages/CrashRecovery/framework/java/android/service/watchdog/ExplicitHealthCheckService.java
@@ -18,15 +18,17 @@
 
 import static android.os.Parcelable.Creator;
 
+import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
-import android.annotation.TestApi;
 import android.app.Service;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.crashrecovery.flags.Flags;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -42,7 +44,9 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 
 /**
  * A service to provide packages supporting explicit health checks and route checks to these
@@ -89,11 +93,10 @@
 
     /**
      * {@link Bundle} key for a {@link String} value.
-     *
-     * {@hide}
      */
+    @FlaggedApi(Flags.FLAG_ENABLE_CRASHRECOVERY)
     public static final String EXTRA_HEALTH_CHECK_PASSED_PACKAGE =
-            "android.service.watchdog.extra.health_check_passed_package";
+            "android.service.watchdog.extra.HEALTH_CHECK_PASSED_PACKAGE";
 
     /**
      * The Intent action that a service must respond to. Add it to the intent filter of the service
@@ -152,7 +155,8 @@
     @NonNull public abstract List<String> onGetRequestedPackages();
 
     private final Handler mHandler = Handler.createAsync(Looper.getMainLooper());
-    @Nullable private RemoteCallback mCallback;
+    @Nullable private Consumer<Bundle> mHealthCheckResultCallback;
+    @Nullable private Executor mCallbackExecutor;
 
     @Override
     @NonNull
@@ -161,30 +165,49 @@
     }
 
     /**
-     * Sets {@link RemoteCallback}, for testing purpose.
+     * Sets a callback to be invoked when an explicit health check passes for a package.
+     * <p>
+     * The callback will receive a {@link Bundle} containing the package name that passed the
+     * health check, identified by the key {@link #EXTRA_HEALTH_CHECK_PASSED_PACKAGE}.
+     * <p>
+     * <b>Note:</b> This API is primarily intended for testing purposes. Calling this outside of a
+     * test environment will override the default callback mechanism used to notify the system
+     * about health check results. Use with caution in production code.
      *
-     * @hide
+     * @param executor The executor on which the callback should be invoked. If {@code null}, the
+     *                 callback will be executed on the main thread.
+     * @param callback A callback that receives a {@link Bundle} containing the package name that
+     *                 passed the health check.
      */
-    @TestApi
-    public void setCallback(@Nullable RemoteCallback callback) {
-        mCallback = callback;
+    @FlaggedApi(Flags.FLAG_ENABLE_CRASHRECOVERY)
+    public final void setHealthCheckResultCallback(@CallbackExecutor @Nullable Executor executor,
+            @Nullable Consumer<Bundle> callback) {
+        mCallbackExecutor = executor;
+        mHealthCheckResultCallback = callback;
     }
+
+    private void executeCallback(@NonNull String packageName) {
+        if (mHealthCheckResultCallback != null) {
+            Objects.requireNonNull(packageName,
+                    "Package passing explicit health check must be non-null");
+            Bundle bundle = new Bundle();
+            bundle.putString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE, packageName);
+            mHealthCheckResultCallback.accept(bundle);
+        } else {
+            Log.wtf(TAG, "System missed explicit health check result for " + packageName);
+        }
+    }
+
     /**
      * Implementors should call this to notify the system when explicit health check passes
      * for {@code packageName};
      */
     public final void notifyHealthCheckPassed(@NonNull String packageName) {
-        mHandler.post(() -> {
-            if (mCallback != null) {
-                Objects.requireNonNull(packageName,
-                        "Package passing explicit health check must be non-null");
-                Bundle bundle = new Bundle();
-                bundle.putString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE, packageName);
-                mCallback.sendResult(bundle);
-            } else {
-                Log.wtf(TAG, "System missed explicit health check result for " + packageName);
-            }
-        });
+        if (mCallbackExecutor != null) {
+            mCallbackExecutor.execute(() -> executeCallback(packageName));
+        } else {
+            mHandler.post(() -> executeCallback(packageName));
+        }
     }
 
     /**
@@ -296,9 +319,7 @@
     private class ExplicitHealthCheckServiceWrapper extends IExplicitHealthCheckService.Stub {
         @Override
         public void setCallback(RemoteCallback callback) throws RemoteException {
-            mHandler.post(() -> {
-                mCallback = callback;
-            });
+            mHandler.post(() -> mHealthCheckResultCallback = callback::sendResult);
         }
 
         @Override
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
index 560e751..8b8ab58 100644
--- a/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
+++ b/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
@@ -770,19 +770,19 @@
      * The minimum value that can be returned by any observer.
      * It represents that no mitigations were available.
      */
-    public static final int LEAST_PACKAGE_HEALTH_OBSERVER_IMPACT =
+    public static final int USER_IMPACT_THRESHOLD_NONE =
             PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
 
     /**
      * The mitigation impact beyond which the user will start noticing the mitigations.
      */
-    public static final int MEDIUM_USER_IMPACT_THRESHOLD =
+    public static final int USER_IMPACT_THRESHOLD_MEDIUM =
             PackageHealthObserverImpact.USER_IMPACT_LEVEL_20;
 
     /**
      * The mitigation impact beyond which the user impact is severely high.
      */
-    public static final int HIGH_USER_IMPACT_THRESHOLD =
+    public static final int USER_IMPACT_THRESHOLD_HIGH =
             PackageHealthObserverImpact.USER_IMPACT_LEVEL_71;
 
     /**
@@ -827,11 +827,9 @@
     public interface PackageHealthObserver {
         /**
          * Called when health check fails for the {@code versionedPackage}.
-         *
-         * Note: if the returned user impact is higher than
-         * {@link #DEFAULT_HIGH_USER_IMPACT_THRESHOLD}, then
-         * {@link #onExecuteHealthCheckMitigation} would be called only in severe device conditions
-         * like boot-loop or network failure.
+         * Note: if the returned user impact is higher than {@link #USER_IMPACT_THRESHOLD_HIGH},
+         * then {@link #onExecuteHealthCheckMitigation} would be called only in severe device
+         * conditions like boot-loop or network failure.
          *
          * @param versionedPackage the package that is failing. This may be null if a native
          *                          service is crashing.
@@ -839,9 +837,9 @@
          * @param mitigationCount the number of times mitigation has been called for this package
          *                        (including this time).
          *
-         *
-         * @return any value greater than {@link #LEAST_PACKAGE_HEALTH_OBSERVER_IMPACT} to express
-         * the impact of mitigation on the user in {@link #onExecuteHealthCheckMitigation}
+         * @return any value greater than {@link #USER_IMPACT_THRESHOLD_NONE} to express
+         * the impact of mitigation on the user in {@link #onExecuteHealthCheckMitigation}.
+         * Returning {@link #USER_IMPACT_THRESHOLD_NONE} would indicate no mitigations available.
          */
         @PackageHealthObserverImpact int onHealthCheckFailed(
                 @Nullable VersionedPackage versionedPackage,
@@ -871,8 +869,9 @@
          * @param mitigationCount the number of times mitigation has been attempted for this
          *                        boot loop (including this time).
          *
-         * @return any value greater than {@link #LEAST_PACKAGE_HEALTH_OBSERVER_IMPACT} to express
-         * the impact of mitigation on the user in {@link #onExecuteBootLoopMitigation}
+         * @return any value greater than {@link #USER_IMPACT_THRESHOLD_NONE} to express
+         * the impact of mitigation on the user in {@link #onExecuteBootLoopMitigation}.
+         * Returning {@link #USER_IMPACT_THRESHOLD_NONE} would indicate no mitigations available.
          */
         default @PackageHealthObserverImpact int onBootLoop(int mitigationCount) {
             return PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
diff --git a/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_middle.xml b/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_middle.xml
index 781373d..327f4220 100644
--- a/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_middle.xml
+++ b/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_middle.xml
@@ -19,6 +19,6 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
         xmlns:tools="http://schemas.android.com/tools" tools:ignore="NewApi">
         <shape android:shape="rectangle">
-            <solid android:color="?androidprv:attr/materialColorSurfaceContainer" />
+            <solid android:color="@androidprv:color/materialColorSurfaceContainer" />
         </shape>
 </inset>
\ No newline at end of file
diff --git a/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_one.xml b/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_one.xml
index f28c354..992fe33 100644
--- a/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_one.xml
+++ b/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_one.xml
@@ -21,6 +21,6 @@
         <shape android:shape="rectangle">
             <corners android:topLeftRadius="4dp" android:topRightRadius="4dp"
             android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp"/>
-            <solid android:color="?androidprv:attr/materialColorSurfaceContainer" />
+            <solid android:color="@androidprv:color/materialColorSurfaceContainer" />
         </shape>
 </inset>
\ No newline at end of file
diff --git a/packages/CredentialManager/res/drawable/more_options_list_item.xml b/packages/CredentialManager/res/drawable/more_options_list_item.xml
index 3f9d815..991b3ff 100644
--- a/packages/CredentialManager/res/drawable/more_options_list_item.xml
+++ b/packages/CredentialManager/res/drawable/more_options_list_item.xml
@@ -24,7 +24,7 @@
     <shape>
         <corners android:topLeftRadius="0dp" android:topRightRadius="0dp"
             android:bottomLeftRadius="4dp" android:bottomRightRadius="4dp"/>
-        <solid android:color="?androidprv:attr/materialColorSurfaceContainer"/>
-        <stroke android:color="?androidprv:attr/materialColorOutlineVariant" android:width="1dp"/>
+        <solid android:color="@androidprv:color/materialColorSurfaceContainer"/>
+        <stroke android:color="@androidprv:color/materialColorOutlineVariant" android:width="1dp"/>
     </shape>
 </inset>
\ No newline at end of file
diff --git a/packages/CredentialManager/res/layout/credman_dropdown_bottom_sheet.xml b/packages/CredentialManager/res/layout/credman_dropdown_bottom_sheet.xml
index 914987a..6f04bd9 100644
--- a/packages/CredentialManager/res/layout/credman_dropdown_bottom_sheet.xml
+++ b/packages/CredentialManager/res/layout/credman_dropdown_bottom_sheet.xml
@@ -35,7 +35,7 @@
             android:layout_gravity="center"
             android:paddingStart="@dimen/autofill_view_left_padding"
             android:src="@drawable/more_horiz_24px"
-            android:tint="?androidprv:attr/materialColorOnSurface"
+            android:tint="@androidprv:color/materialColorOnSurface"
             android:contentDescription="@string/more_options_content_description"
             android:background="@null"/>
 
@@ -53,7 +53,7 @@
             android:id="@android:id/text1"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:textColor="?androidprv:attr/materialColorOnSurface"
+            android:textColor="@androidprv:color/materialColorOnSurface"
             style="@style/autofill.TextTitle"/>
     </LinearLayout>
 
diff --git a/packages/CredentialManager/res/layout/credman_dropdown_presentation_layout.xml b/packages/CredentialManager/res/layout/credman_dropdown_presentation_layout.xml
index 3fc6154..d00a229 100644
--- a/packages/CredentialManager/res/layout/credman_dropdown_presentation_layout.xml
+++ b/packages/CredentialManager/res/layout/credman_dropdown_presentation_layout.xml
@@ -35,7 +35,7 @@
                     android:layout_gravity="center"
                     android:layout_alignParentStart="true"
                     android:paddingStart="@dimen/autofill_view_left_padding"
-                    app:tint="?androidprv:attr/materialColorOnSurface"
+                    app:tint="@androidprv:color/materialColorOnSurface"
                     android:background="@null"/>
 
                 <LinearLayout
@@ -53,7 +53,7 @@
                             android:id="@android:id/text1"
                             android:layout_width="wrap_content"
                             android:layout_height="wrap_content"
-                            android:textColor="?androidprv:attr/materialColorOnSurface"
+                            android:textColor="@androidprv:color/materialColorOnSurface"
                             android:textDirection="locale"
                             style="@style/autofill.TextTitle"/>
 
@@ -61,7 +61,7 @@
                             android:id="@android:id/text2"
                             android:layout_width="wrap_content"
                             android:layout_height="wrap_content"
-                            android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+                            android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
                             android:textDirection="locale"
                             style="@style/autofill.TextSubtitle"/>
 
diff --git a/packages/CredentialManager/res/values/colors.xml b/packages/CredentialManager/res/values/colors.xml
index 9d31b35..8d37d47 100644
--- a/packages/CredentialManager/res/values/colors.xml
+++ b/packages/CredentialManager/res/values/colors.xml
@@ -19,8 +19,8 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
 
     <!-- These colors are used for Remote Views. -->
-    <color name="onSurface">?androidprv:attr/materialColorOnSurface</color>
-    <color name="onSurfaceVariant">?androidprv:attr/materialColorOnSurfaceVariant</color>
-    <color name="surfaceDim">?androidprv:attr/materialColorSurfaceDim</color>
-    <color name="surfaceContainer">?androidprv:attr/materialColorSurfaceContainer</color>
+    <color name="onSurface">@androidprv:color/materialColorOnSurface</color>
+    <color name="onSurfaceVariant">@androidprv:color/materialColorOnSurfaceVariant</color>
+    <color name="surfaceDim">@androidprv:color/materialColorSurfaceDim</color>
+    <color name="surfaceContainer">@androidprv:color/materialColorSurfaceContainer</color>
 </resources>
\ No newline at end of file
diff --git a/packages/CredentialManager/wear/res/values-hi/strings.xml b/packages/CredentialManager/wear/res/values-hi/strings.xml
index a061453..405d3f8 100644
--- a/packages/CredentialManager/wear/res/values-hi/strings.xml
+++ b/packages/CredentialManager/wear/res/values-hi/strings.xml
@@ -22,8 +22,8 @@
     <string name="use_password_title" msgid="4655101984031246476">"क्या आपको पासवर्ड का इस्तेमाल करना है?"</string>
     <string name="dialog_dismiss_button" msgid="989567669882005067">"खारिज करें"</string>
     <string name="dialog_continue_button" msgid="8630290044077052145">"जारी रखें"</string>
-    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"साइन इन करने के विकल्प"</string>
-    <string name="sign_in_options_title" msgid="6720572645638986680">"साइन इन करने के विकल्प"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"साइन-इन करने के विकल्प"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"साइन-इन करने के विकल्प"</string>
     <string name="provider_list_title" msgid="6803918216129492212">"साइन-इन क्रेडेंशियल मैनेज करें"</string>
     <string name="choose_sign_in_title" msgid="3616025924746872202">"साइन इन करने का कोई तरीका चुनें"</string>
     <string name="choose_passkey_title" msgid="8459270617632817465">"कोई पासकी चुनें"</string>
diff --git a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
index 607ec1c..a078f75 100644
--- a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
+++ b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
@@ -16,8 +16,6 @@
 
 package com.android.server.ondeviceintelligence;
 
-import static android.app.ondeviceintelligence.flags.Flags.enableOnDeviceIntelligenceModule;
-
 import static android.app.ondeviceintelligence.OnDeviceIntelligenceManager.ON_DEVICE_INTELLIGENCE_IDLE_TIMEOUT_MS;
 import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService.DEVICE_CONFIG_UPDATE_BUNDLE_KEY;
 import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService.MODEL_LOADED_BROADCAST_INTENT;
@@ -180,10 +178,8 @@
         publishBinderService(
                 Context.ON_DEVICE_INTELLIGENCE_SERVICE, getOnDeviceIntelligenceManagerService(),
                 /* allowIsolated = */ true);
-        if (enableOnDeviceIntelligenceModule()) {
-            LocalManagerRegistry.addManager(OnDeviceIntelligenceManagerLocal.class,
+        LocalManagerRegistry.addManager(OnDeviceIntelligenceManagerLocal.class,
                     this::getRemoteInferenceServiceUid);
-        }
     }
 
     @Override
@@ -198,20 +194,6 @@
         }
     }
 
-    @Override
-    public void onUserUnlocked(@NonNull TargetUser user) {
-        Slog.d(TAG, "onUserUnlocked: " + user.getUserHandle());
-        //connect to remote services(if available) during boot.
-        if (user.getUserHandle().equals(UserHandle.SYSTEM)) {
-            try {
-                ensureRemoteInferenceServiceInitialized(/* throwServiceIfInvalid */ false);
-                ensureRemoteIntelligenceServiceInitialized(/* throwServiceIfInvalid */ false);
-            } catch (Exception e) {
-                Slog.w(TAG, "Couldn't pre-start remote ondeviceintelligence services.", e);
-            }
-        }
-    }
-
     private void onDeviceConfigChange(@NonNull Set<String> keys) {
         if (keys.contains(KEY_SERVICE_ENABLED)) {
             mIsServiceEnabled = isServiceEnabled();
@@ -778,13 +760,8 @@
             if (mTemporaryConfigNamespace != null) {
                 return mTemporaryConfigNamespace;
             }
-            return mContext.getResources()
-                    .getString(
-                            mContext.getResources()
-                                    .getIdentifier(
-                                            "config_defaultOnDeviceIntelligenceDeviceConfigNamespace",
-                                            "string",
-                                            "android"));
+            return mContext.getResources().getString(
+                    android.R.string.config_defaultOnDeviceIntelligenceDeviceConfigNamespace);
         }
     }
 
@@ -966,22 +943,10 @@
                 return mTemporaryServiceNames;
             }
         }
-        return new String[]{
-                mContext.getResources()
-                        .getString(
-                        mContext.getResources()
-                                .getIdentifier(
-                                        "config_defaultOnDeviceIntelligenceService",
-                                        "string",
-                                        "android")),
-                mContext.getResources()
-                        .getString(
-                        mContext.getResources()
-                                .getIdentifier(
-                                        "config_defaultOnDeviceSandboxedInferenceService",
-                                        "string",
-                                        "android"))
-        };
+        return new String[]{mContext.getResources().getString(
+                android.R.string.config_defaultOnDeviceIntelligenceService),
+                mContext.getResources().getString(
+                        android.R.string.config_defaultOnDeviceSandboxedInferenceService)};
     }
 
     protected String[] getBroadcastKeys() throws Resources.NotFoundException {
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
index 379dfe3..635ae20 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -36,6 +36,7 @@
 import android.os.Bundle;
 import android.os.Process;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.EventLog;
 import android.util.Log;
@@ -62,9 +63,12 @@
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        boolean testOverrideForPiaV2 = Settings.System.getInt(getContentResolver(),
+                "use_pia_v2", 0) == 1;
+        boolean usePiaV2aConfig = usePiaV2();
 
-        if (usePiaV2()) {
-            Log.i(TAG, "Using Pia V2");
+        if (usePiaV2aConfig || testOverrideForPiaV2) {
+            logReasonForDebug(usePiaV2aConfig, testOverrideForPiaV2);
 
             Intent piaV2 = new Intent(getIntent());
             piaV2.putExtra(InstallLaunch.EXTRA_CALLING_PKG_NAME, getLaunchedFromPackage());
@@ -381,4 +385,20 @@
         }
         return null;
     }
+
+    private void logReasonForDebug(boolean usePiaV2aConfig, boolean testOverrideForPiaV2) {
+        StringBuilder sb = new StringBuilder("Using Pia V2 due to: ");
+        boolean aconfigUsed = false;
+        if (usePiaV2aConfig) {
+            sb.append("aconfig flag USE_PIA_V2");
+            aconfigUsed = true;
+        }
+        if (testOverrideForPiaV2) {
+            if (aconfigUsed) {
+                sb.append(" and ");
+            }
+            sb.append("testOverrideForPiaV2.");
+        }
+        Log.i(TAG, sb.toString());
+    }
 }
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml
index 8d6f0da4..fdc5975 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml
@@ -20,7 +20,7 @@
        xmlns:tools="http://schemas.android.com/tools"
        tools:targetApi="28"
        android:shape="rectangle">
-    <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh" />
+    <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh" />
     <corners
         android:topLeftRadius="?android:attr/dialogCornerRadius"
         android:topRightRadius="0dp"
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml
index 3072772..405c452 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml
@@ -20,7 +20,7 @@
        xmlns:tools="http://schemas.android.com/tools"
        tools:targetApi="28"
        android:shape="rectangle">
-    <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh" />
+    <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh" />
     <corners
         android:topLeftRadius="0dp"
         android:topRightRadius="?android:attr/dialogCornerRadius"
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_bk.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_bk.xml
index f1790f9..187e612 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_bk.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_bk.xml
@@ -20,7 +20,7 @@
        xmlns:tools="http://schemas.android.com/tools"
        tools:targetApi="28"
        android:shape="rectangle">
-    <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh" />
+    <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh" />
     <corners
         android:radius="?android:attr/dialogCornerRadius"
     />
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/square_bk.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/square_bk.xml
index d56c843..0182b4c 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/drawable/square_bk.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/square_bk.xml
@@ -18,7 +18,7 @@
 <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="?androidprv:attr/materialColorSurfaceContainerHigh" />
+    <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh" />
     <corners
         android:radius="0dp"
     />
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/values-v35/styles_expressive.xml b/packages/SettingsLib/ActionButtonsPreference/res/values-v35/styles_expressive.xml
index cc948a6..fd8cecb 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/values-v35/styles_expressive.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/values-v35/styles_expressive.xml
@@ -22,12 +22,13 @@
         <item name="iconGravity">textTop</item>
     </style>
 
-    <style name="SettingsLibActionButton.Expressive.Label" parent="SettingsLibTextAppearance.Emphasized.Title.Small">
+    <style name="SettingsLibActionButton.Expressive.Label" parent="">
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
         <item name="android:minWidth">@dimen/settingslib_expressive_space_small3</item>
         <item name="android:minHeight">@dimen/settingslib_expressive_space_small3</item>
-        <item name="android:textColor">@color/settingslib_materialColorOnSurface</item>
+        <item name="android:textAppearance">@style/TextAppearance.SettingsLib.TitleSmall.Emphasized</item>
+        <item name="android:textColor">@color/settingslib_text_color_primary</item>
         <item name="android:layout_gravity">center</item>
     </style>
 
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index a3da93d..d739aaf 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -65,6 +65,7 @@
     libs:[
         // This flag library has been added in frameworks jar
         "aconfig_settingslib_flags_java_lib",
+        "wifi_framework_aconfig_flags_lib",
     ],
     plugins: ["androidx.room_room-compiler-plugin"],
     use_resource_processor: true,
diff --git a/packages/SettingsLib/CardPreference/res/layout/settingslib_expressive_preference_card.xml b/packages/SettingsLib/CardPreference/res/layout/settingslib_expressive_preference_card.xml
index 716ed41..9018bac 100644
--- a/packages/SettingsLib/CardPreference/res/layout/settingslib_expressive_preference_card.xml
+++ b/packages/SettingsLib/CardPreference/res/layout/settingslib_expressive_preference_card.xml
@@ -40,7 +40,6 @@
 
             <ImageView
                 android:id="@android:id/icon"
-                android:src="@drawable/settingslib_arrow_drop_down"
                 android:layout_width="@dimen/settingslib_expressive_space_medium3"
                 android:layout_height="@dimen/settingslib_expressive_space_medium3"
                 android:scaleType="centerInside"/>
@@ -60,16 +59,12 @@
                 android:id="@android:id/title"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:hyphenationFrequency="normalFast"
-                android:lineBreakWordStyle="phrase"
                 android:textAppearance="@style/TextAppearance.CardTitle.SettingsLib"/>
 
             <TextView
                 android:id="@android:id/summary"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:hyphenationFrequency="normalFast"
-                android:lineBreakWordStyle="phrase"
                 android:textAppearance="@style/TextAppearance.CardSummary.SettingsLib"/>
 
         </LinearLayout>
diff --git a/packages/SettingsLib/CardPreference/res/values/styles_expressive.xml b/packages/SettingsLib/CardPreference/res/values/styles_expressive.xml
index 4cbdea5..287b13f 100644
--- a/packages/SettingsLib/CardPreference/res/values/styles_expressive.xml
+++ b/packages/SettingsLib/CardPreference/res/values/styles_expressive.xml
@@ -17,14 +17,12 @@
 
 <resources>
     <style name="TextAppearance.CardTitle.SettingsLib"
-        parent="@style/TextAppearance.PreferenceTitle.SettingsLib">
+        parent="@style/TextAppearance.SettingsLib.TitleMedium.Emphasized">
         <item name="android:textColor">@color/settingslib_materialColorOnPrimary</item>
-        <item name="android:textSize">20sp</item>
     </style>
 
     <style name="TextAppearance.CardSummary.SettingsLib"
-        parent="@style/TextAppearance.PreferenceSummary.SettingsLib">
+        parent="@style/TextAppearance.SettingsLib.LabelMedium">
         <item name="android:textColor">@color/settingslib_materialColorOnSecondary</item>
-        <item name="android:textSize">14sp</item>
     </style>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/drawable-v35/settingslib_expressive_icon_back.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/drawable-v35/settingslib_expressive_icon_back.xml
index ccbe20e..9986a60 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/drawable-v35/settingslib_expressive_icon_back.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/drawable-v35/settingslib_expressive_icon_back.xml
@@ -17,12 +17,9 @@
 
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
     <item
-        android:start="16dp"
-        android:end="16dp"
-        android:top="4dp"
-        android:bottom="4dp">
+        android:start="16dp">
         <shape>
-            <size android:width="32dp" android:height="40dp" />
+            <size android:width="40dp" android:height="40dp" />
             <solid android:color="@color/settingslib_materialColorSurfaceContainerHighest" />
             <corners
                 android:radius="100dp" />
@@ -30,23 +27,21 @@
     </item>
 
     <item
-        android:width="24dp"
-        android:height="24dp"
+        android:width="16dp"
+        android:height="16dp"
         android:gravity="center"
         android:start="16dp"
-        android:end="16dp"
-        android:top="4dp"
-        android:bottom="4dp">
+>
         <vector
-            android:width="24dp"
-            android:height="24dp"
-            android:viewportWidth="960"
-            android:viewportHeight="960"
+            android:width="16dp"
+            android:height="16dp"
+            android:viewportWidth="16"
+            android:viewportHeight="16"
             android:tint="@color/settingslib_materialColorOnSurfaceVariant"
             android:autoMirrored="true">
             <path
                 android:fillColor="@android:color/white"
-                android:pathData="M313,520L537,744L480,800L160,480L480,160L537,216L313,440L800,440L800,520L313,520Z"/>
+                android:pathData="M3.626,9L8.526,13.9C8.726,14.1 8.817,14.333 8.801,14.6C8.801,14.867 8.701,15.1 8.501,15.3C8.301,15.483 8.067,15.583 7.801,15.6C7.534,15.6 7.301,15.5 7.101,15.3L0.501,8.7C0.401,8.6 0.326,8.492 0.276,8.375C0.242,8.258 0.226,8.133 0.226,8C0.226,7.867 0.242,7.742 0.276,7.625C0.326,7.508 0.401,7.4 0.501,7.3L7.101,0.7C7.284,0.517 7.509,0.425 7.776,0.425C8.059,0.425 8.301,0.517 8.501,0.7C8.701,0.9 8.801,1.142 8.801,1.425C8.801,1.692 8.701,1.925 8.501,2.125L3.626,7H14.801C15.084,7 15.317,7.1 15.501,7.3C15.701,7.483 15.801,7.717 15.801,8C15.801,8.283 15.701,8.525 15.501,8.725C15.317,8.908 15.084,9 14.801,9H3.626Z"/>
         </vector>
     </item>
 </layer-list>
\ No newline at end of file
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night-v35/themes.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night-v35/themes.xml
index e68253e..fadcf7b 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night-v35/themes.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night-v35/themes.xml
@@ -18,7 +18,7 @@
     <style name="Theme.CollapsingToolbar.Settings" parent="@style/Theme.MaterialComponents.DayNight">
         <item name="elevationOverlayEnabled">true</item>
         <item name="elevationOverlayColor">?attr/colorPrimary</item>
-        <item name="colorPrimary">@color/settingslib_materialColorInverseOnSurface</item>
+        <item name="colorPrimary">@color/settingslib_materialColorOnSurfaceInverse</item>
         <item name="colorAccent">@color/settingslib_materialColorPrimaryFixed</item>
     </style>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/styles_expressive.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/styles_expressive.xml
index d58c2c2..37a7810 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/styles_expressive.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/styles_expressive.xml
@@ -33,12 +33,12 @@
         <item name="contentScrim">@color/settingslib_materialColorSurfaceContainer</item>
     </style>
 
-    <style name="SettingsLibCollapsingToolbarTitle.Collapsed" parent="@android:style/TextAppearance.DeviceDefault.Headline">
+    <style name="SettingsLibCollapsingToolbarTitle.Collapsed" parent="@style/TextAppearance.SettingsLib.TitleLarge.Emphasized">
         <!--set dp because we don't want size adjust when font size change-->
-        <item name="android:textSize">20dp</item>
+        <item name="android:textSize">22dp</item>
     </style>
 
-    <style name="SettingsLibCollapsingToolbarTitle.Expanded" parent="CollapsingToolbarTitle.Collapsed">
+    <style name="SettingsLibCollapsingToolbarTitle.Expanded" parent="@style/TextAppearance.SettingsLib.DisplaySmall.Emphasized">
         <item name="android:textSize">36dp</item>
     </style>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/themes.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/themes.xml
index f7c9aac..7c9d1a4 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/themes.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/themes.xml
@@ -18,7 +18,7 @@
     <style name="Theme.CollapsingToolbar.Settings" parent="@style/Theme.MaterialComponents.DayNight">
         <item name="elevationOverlayEnabled">true</item>
         <item name="elevationOverlayColor">?attr/colorPrimary</item>
-        <item name="colorPrimary">@color/settingslib_materialColorInverseOnSurface</item>
+        <item name="colorPrimary">@color/settingslib_materialColorOnSurfaceInverse</item>
         <item name="colorAccent">@color/settingslib_materialColorPrimary</item>
     </style>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyValueStore.kt b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyValueStore.kt
index 5f1f8df..472ffa9 100644
--- a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyValueStore.kt
+++ b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyValueStore.kt
@@ -47,6 +47,37 @@
      * @param value value to set, null means remove
      */
     fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?)
+
+    /** Gets the boolean value of given key. */
+    fun getBoolean(key: String): Boolean? = getValue(key, Boolean::class.javaObjectType)
+
+    /** Sets boolean value for given key, null value means delete the key from data store. */
+    fun setBoolean(key: String, value: Boolean?) =
+        setValue(key, Boolean::class.javaObjectType, value)
+
+    /** Gets the float value of given key. */
+    fun getFloat(key: String): Float? = getValue(key, Float::class.javaObjectType)
+
+    /** Sets float value for given key, null value means delete the key from data store. */
+    fun setFloat(key: String, value: Float?) = setValue(key, Float::class.javaObjectType, value)
+
+    /** Gets the int value of given key. */
+    fun getInt(key: String): Int? = getValue(key, Int::class.javaObjectType)
+
+    /** Sets int value for given key, null value means delete the key from data store. */
+    fun setInt(key: String, value: Int?) = setValue(key, Int::class.javaObjectType, value)
+
+    /** Gets the long value of given key. */
+    fun getLong(key: String): Long? = getValue(key, Long::class.javaObjectType)
+
+    /** Sets long value for given key, null value means delete the key from data store. */
+    fun setLong(key: String, value: Long?) = setValue(key, Long::class.javaObjectType, value)
+
+    /** Gets the string value of given key. */
+    fun getString(key: String): String? = getValue(key, String::class.javaObjectType)
+
+    /** Sets string value for given key, null value means delete the key from data store. */
+    fun setString(key: String, value: String?) = setValue(key, String::class.javaObjectType, value)
 }
 
 /** [SharedPreferences] based [KeyValueStore]. */
diff --git a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsStore.kt b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsStore.kt
index d6e7a89..3f1a4998 100644
--- a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsStore.kt
+++ b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsStore.kt
@@ -50,37 +50,6 @@
         contentResolver.unregisterContentObserver(contentObserver)
     }
 
-    /** Gets the boolean value of given key. */
-    fun getBoolean(key: String): Boolean? = getValue(key, Boolean::class.javaObjectType)
-
-    /** Sets boolean value for given key, null value means delete the key from data store. */
-    fun setBoolean(key: String, value: Boolean?) =
-        setValue(key, Boolean::class.javaObjectType, value)
-
-    /** Gets the float value of given key. */
-    fun getFloat(key: String): Float? = getValue(key, Float::class.javaObjectType)
-
-    /** Sets float value for given key, null value means delete the key from data store. */
-    fun setFloat(key: String, value: Float?) = setValue(key, Float::class.javaObjectType, value)
-
-    /** Gets the int value of given key. */
-    fun getInt(key: String): Int? = getValue(key, Int::class.javaObjectType)
-
-    /** Sets int value for given key, null value means delete the key from data store. */
-    fun setInt(key: String, value: Int?) = setValue(key, Int::class.javaObjectType, value)
-
-    /** Gets the long value of given key. */
-    fun getLong(key: String): Long? = getValue(key, Long::class.javaObjectType)
-
-    /** Sets long value for given key, null value means delete the key from data store. */
-    fun setLong(key: String, value: Long?) = setValue(key, Long::class.javaObjectType, value)
-
-    /** Gets the string value of given key. */
-    fun getString(key: String): String? = getValue(key, String::class.javaObjectType)
-
-    /** Sets string value for given key, null value means delete the key from data store. */
-    fun setString(key: String, value: String?) = setValue(key, String::class.javaObjectType, value)
-
     /** Tag for logging. */
     abstract val tag: String
 }
diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt
index a768b5e..606710e 100644
--- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt
+++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt
@@ -55,9 +55,9 @@
 import com.android.settingslib.metadata.ReadWritePermit
 import com.android.settingslib.preference.PreferenceScreenFactory
 import com.android.settingslib.preference.PreferenceScreenProvider
+import java.util.Locale
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.withContext
-import java.util.Locale
 
 private const val TAG = "PreferenceGraphBuilder"
 
@@ -399,15 +399,11 @@
             value = preferenceValueProto {
                 when (metadata) {
                     is BooleanValue ->
-                        metadata
-                            .storage(context)
-                            .getValue(metadata.key, Boolean::class.javaObjectType)
-                            ?.let { booleanValue = it }
+                        metadata.storage(context).getBoolean(metadata.key)?.let {
+                            booleanValue = it
+                        }
                     is RangeValue -> {
-                        metadata
-                            .storage(context)
-                            .getValue(metadata.key, Int::class.javaObjectType)
-                            ?.let { intValue = it }
+                        metadata.storage(context).getInt(metadata.key)?.let { intValue = it }
                     }
                     else -> {}
                 }
diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt
index 7cfce0d..56b1693 100644
--- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt
+++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt
@@ -146,7 +146,7 @@
                 val booleanValue = value.booleanValue
                 val resultCode = metadata.checkWritePermit(booleanValue)
                 if (resultCode != PreferenceSetterResult.OK) return resultCode
-                storage.setValue(key, Boolean::class.javaObjectType, booleanValue)
+                storage.setBoolean(key, booleanValue)
                 return PreferenceSetterResult.OK
             } else if (value.hasIntValue()) {
                 val intValue = value.intValue
@@ -155,7 +155,7 @@
                 if (metadata is RangeValue && !metadata.isValidValue(application, intValue)) {
                     return PreferenceSetterResult.INVALID_REQUEST
                 }
-                storage.setValue(key, Int::class.javaObjectType, intValue)
+                storage.setInt(key, intValue)
                 return PreferenceSetterResult.OK
             }
         } catch (e: Exception) {
diff --git a/packages/SettingsLib/IntroPreference/res/layout/settingslib_expressive_preference_intro.xml b/packages/SettingsLib/IntroPreference/res/layout/settingslib_expressive_preference_intro.xml
index 2edc001..43cf6aa 100644
--- a/packages/SettingsLib/IntroPreference/res/layout/settingslib_expressive_preference_intro.xml
+++ b/packages/SettingsLib/IntroPreference/res/layout/settingslib_expressive_preference_intro.xml
@@ -26,7 +26,6 @@
 
         <ImageView
             android:id="@android:id/icon"
-            android:src="@drawable/settingslib_arrow_drop_down"
             style="@style/SettingsLibEntityHeaderIcon"/>
 
         <TextView
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
index 106802e..73728bcd 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
@@ -32,6 +32,7 @@
 import android.widget.TextView;
 
 import androidx.annotation.ColorInt;
+import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 
 import com.android.settingslib.widget.mainswitch.R;
@@ -42,7 +43,7 @@
 /**
  * MainSwitchBar is a View with a customized Switch.
  * This component is used as the main switch of the page
- * to enable or disable the prefereces on the page.
+ * to enable or disable the preferences on the page.
  */
 public class MainSwitchBar extends LinearLayout implements OnCheckedChangeListener {
 
@@ -58,6 +59,8 @@
     protected CompoundButton mSwitch;
     private final View mFrameView;
 
+    private @Nullable PreChangeListener mPreChangeListener;
+
     public MainSwitchBar(Context context) {
         this(context, null);
     }
@@ -138,10 +141,20 @@
 
     @Override
     public boolean performClick() {
-        mSwitch.performClick();
+        if (callPreChangeListener()) {
+            mSwitch.performClick();
+        }
         return super.performClick();
     }
 
+    protected boolean callPreChangeListener() {
+        return mPreChangeListener == null || mPreChangeListener.preChange(!mSwitch.isChecked());
+    }
+
+    public void setPreChangeListener(@Nullable PreChangeListener preChangeListener) {
+        mPreChangeListener = preChangeListener;
+    }
+
     /**
      * Update the switch status
      */
@@ -271,7 +284,7 @@
         }
     }
 
-    static class SavedState extends BaseSavedState {
+    public static class SavedState extends BaseSavedState {
         boolean mChecked;
         boolean mVisible;
 
@@ -341,4 +354,16 @@
 
         requestLayout();
     }
+
+    /**
+     * Listener callback before switch is toggled.
+     */
+    public interface PreChangeListener {
+        /**
+         * Returns if the new value can be set.
+         *
+         * When false is return, the switch toggle is not triggered at all.
+         */
+        boolean preChange(boolean isCheck);
+    }
 }
diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt
index 6e86fa7..c1edbdc 100644
--- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt
+++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt
@@ -107,20 +107,11 @@
      *
      * UI framework normally does not allow user to interact with the preference widget when it is
      * disabled.
-     *
-     * [dependencyOfEnabledState] is provided to support dependency, the [shouldDisableDependents]
-     * value of dependent preference is used to decide enabled state.
      */
-    fun isEnabled(context: Context): Boolean {
-        val dependency = dependencyOfEnabledState(context) ?: return true
-        return !dependency.shouldDisableDependents(context)
-    }
+    fun isEnabled(context: Context): Boolean = true
 
-    /** Returns the key of depended preference to decide the enabled state. */
-    fun dependencyOfEnabledState(context: Context): PreferenceMetadata? = null
-
-    /** Returns whether this preference's dependents should be disabled. */
-    fun shouldDisableDependents(context: Context): Boolean = !isEnabled(context)
+    /** Returns the keys of depended preferences. */
+    fun dependencies(context: Context): Array<String> = arrayOf()
 
     /** Returns if the preference is persistent in datastore. */
     fun isPersistent(context: Context): Boolean = this is PersistentPreference<*>
@@ -174,13 +165,11 @@
 }
 
 /** Metadata of preference group. */
-@AnyThread
-interface PreferenceGroup : PreferenceMetadata
+@AnyThread interface PreferenceGroup : PreferenceMetadata
 
 /** Metadata of preference category. */
 @AnyThread
-open class PreferenceCategory(override val key: String, override val title: Int) :
-    PreferenceGroup
+open class PreferenceCategory(override val key: String, override val title: Int) : PreferenceGroup
 
 /** Metadata of preference screen. */
 @AnyThread
diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt
index 6704ecc..3dd1594 100644
--- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt
+++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt
@@ -21,6 +21,7 @@
 import android.content.Intent
 import android.os.Bundle
 import androidx.lifecycle.LifecycleCoroutineScope
+import com.android.settingslib.datastore.KeyValueStore
 import kotlinx.coroutines.CoroutineScope
 
 /**
@@ -157,6 +158,9 @@
      */
     abstract fun <T : Any> requirePreference(key: String): T
 
+    /** Returns the [KeyValueStore] attached to the preference of given key *on the same screen*. */
+    abstract fun getKeyValueStore(key: String): KeyValueStore?
+
     /** Notifies that preference state of given key is changed and updates preference widget UI. */
     abstract fun notifyPreferenceChange(key: String)
 
diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceTypes.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceTypes.kt
index b64f5dc..87bd261 100644
--- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceTypes.kt
+++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceTypes.kt
@@ -16,19 +16,10 @@
 
 package com.android.settingslib.metadata
 
-import android.content.Context
 import androidx.annotation.StringRes
 
-/**
- * Common base class for preferences that have two selectable states, save a boolean value, and may
- * have dependent preferences that are enabled/disabled based on the current state.
- */
-interface TwoStatePreference : PreferenceMetadata, PersistentPreference<Boolean>, BooleanValue {
-
-    override fun shouldDisableDependents(context: Context) =
-        storage(context).getValue(key, Boolean::class.javaObjectType) != true ||
-            super.shouldDisableDependents(context)
-}
+/** Common base class for preferences that have two selectable states and save a boolean value. */
+interface TwoStatePreference : PreferenceMetadata, PersistentPreference<Boolean>, BooleanValue
 
 /** A preference that provides a two-state toggleable option. */
 open class SwitchPreference
@@ -42,7 +33,4 @@
 /** A preference that provides a two-state toggleable option that can be used as a main switch. */
 open class MainSwitchPreference
 @JvmOverloads
-constructor(
-    override val key: String,
-    @StringRes override val title: Int = 0,
-) : TwoStatePreference
\ No newline at end of file
+constructor(override val key: String, @StringRes override val title: Int = 0) : TwoStatePreference
diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceDataStoreAdapter.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceDataStoreAdapter.kt
index 7601b9a..f0f854a 100644
--- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceDataStoreAdapter.kt
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceDataStoreAdapter.kt
@@ -23,38 +23,31 @@
 class PreferenceDataStoreAdapter(val keyValueStore: KeyValueStore) : PreferenceDataStore() {
 
     override fun getBoolean(key: String, defValue: Boolean): Boolean =
-        keyValueStore.getValue(key, Boolean::class.javaObjectType) ?: defValue
+        keyValueStore.getBoolean(key) ?: defValue
 
     override fun getFloat(key: String, defValue: Float): Float =
-        keyValueStore.getValue(key, Float::class.javaObjectType) ?: defValue
+        keyValueStore.getFloat(key) ?: defValue
 
-    override fun getInt(key: String, defValue: Int): Int =
-        keyValueStore.getValue(key, Int::class.javaObjectType) ?: defValue
+    override fun getInt(key: String, defValue: Int): Int = keyValueStore.getInt(key) ?: defValue
 
-    override fun getLong(key: String, defValue: Long): Long =
-        keyValueStore.getValue(key, Long::class.javaObjectType) ?: defValue
+    override fun getLong(key: String, defValue: Long): Long = keyValueStore.getLong(key) ?: defValue
 
     override fun getString(key: String, defValue: String?): String? =
-        keyValueStore.getValue(key, String::class.javaObjectType) ?: defValue
+        keyValueStore.getString(key) ?: defValue
 
     @Suppress("UNCHECKED_CAST")
     override fun getStringSet(key: String, defValues: Set<String>?): Set<String>? =
         (keyValueStore.getValue(key, Set::class.javaObjectType) as Set<String>?) ?: defValues
 
-    override fun putBoolean(key: String, value: Boolean) =
-        keyValueStore.setValue(key, Boolean::class.javaObjectType, value)
+    override fun putBoolean(key: String, value: Boolean) = keyValueStore.setBoolean(key, value)
 
-    override fun putFloat(key: String, value: Float) =
-        keyValueStore.setValue(key, Float::class.javaObjectType, value)
+    override fun putFloat(key: String, value: Float) = keyValueStore.setFloat(key, value)
 
-    override fun putInt(key: String, value: Int) =
-        keyValueStore.setValue(key, Int::class.javaObjectType, value)
+    override fun putInt(key: String, value: Int) = keyValueStore.setInt(key, value)
 
-    override fun putLong(key: String, value: Long) =
-        keyValueStore.setValue(key, Long::class.javaObjectType, value)
+    override fun putLong(key: String, value: Long) = keyValueStore.setLong(key, value)
 
-    override fun putString(key: String, value: String?) =
-        keyValueStore.setValue(key, String::class.javaObjectType, value)
+    override fun putString(key: String, value: String?) = keyValueStore.setString(key, value)
 
     override fun putStringSet(key: String, values: Set<String>?) =
         keyValueStore.setValue(key, Set::class.javaObjectType, values)
diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
index 6fc9357..a9e20f28 100644
--- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
@@ -67,6 +67,11 @@
 
             override fun <T : Any> requirePreference(key: String) = findPreference<T>(key)!!
 
+            override fun getKeyValueStore(key: String) =
+                (findPreference<Preference>(key)?.preferenceDataStore
+                        as? PreferenceDataStoreAdapter)
+                    ?.keyValueStore
+
             override fun notifyPreferenceChange(key: String) =
                 notifyChange(key, CHANGE_REASON_STATE)
 
@@ -92,14 +97,14 @@
         val preferencesBuilder = ImmutableMap.builder<String, PreferenceHierarchyNode>()
         val dependenciesBuilder = ImmutableMultimap.builder<String, String>()
         val lifecycleAwarePreferences = mutableListOf<PreferenceLifecycleProvider>()
-        fun PreferenceMetadata.addDependency(dependency: PreferenceMetadata) {
-            dependenciesBuilder.put(key, dependency.key)
-        }
 
         fun PreferenceHierarchyNode.addNode() {
             metadata.let {
-                preferencesBuilder.put(it.key, this)
-                it.dependencyOfEnabledState(context)?.addDependency(it)
+                val key = it.key
+                preferencesBuilder.put(key, this)
+                for (dependency in it.dependencies(context)) {
+                    dependenciesBuilder.put(dependency, key)
+                }
                 if (it is PreferenceLifecycleProvider) lifecycleAwarePreferences.add(it)
             }
         }
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant12.xml b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant12.xml
new file mode 100644
index 0000000..f125425
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant12.xml
@@ -0,0 +1,20 @@
+<?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">
+    <item android:color="@android:color/system_neutral2_600" android:lStar="12"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant17.xml b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant17.xml
new file mode 100644
index 0000000..36a7819
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant17.xml
@@ -0,0 +1,20 @@
+<?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">
+    <item android:color="@android:color/system_neutral2_600" android:lStar="17"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant22.xml b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant22.xml
new file mode 100644
index 0000000..0ef31d0
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant22.xml
@@ -0,0 +1,20 @@
+<?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">
+    <item android:color="@android:color/system_neutral2_600" android:lStar="22"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant24.xml b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant24.xml
new file mode 100644
index 0000000..6797f82
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant24.xml
@@ -0,0 +1,20 @@
+<?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">
+    <item android:color="@android:color/system_neutral2_600" android:lStar="24"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant4.xml b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant4.xml
new file mode 100644
index 0000000..ff7df55
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant4.xml
@@ -0,0 +1,20 @@
+<?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">
+    <item android:color="@android:color/system_neutral2_600" android:lStar="4"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant6.xml b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant6.xml
new file mode 100644
index 0000000..8da5daf
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant6.xml
@@ -0,0 +1,20 @@
+<?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">
+    <item android:color="@android:color/system_neutral2_600" android:lStar="6"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant87.xml b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant87.xml
new file mode 100644
index 0000000..227baee
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant87.xml
@@ -0,0 +1,20 @@
+<?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">
+    <item android:color="@android:color/system_neutral2_600" android:lStar="87"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant92.xml b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant92.xml
new file mode 100644
index 0000000..f456438
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant92.xml
@@ -0,0 +1,20 @@
+<?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">
+    <item android:color="@android:color/system_neutral2_600" android:lStar="92"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant94.xml b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant94.xml
new file mode 100644
index 0000000..bb4e03d
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant94.xml
@@ -0,0 +1,20 @@
+<?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">
+    <item android:color="@android:color/system_neutral2_600" android:lStar="94"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant96.xml b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant96.xml
new file mode 100644
index 0000000..949b196
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant96.xml
@@ -0,0 +1,20 @@
+<?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">
+    <item android:color="@android:color/system_neutral2_600" android:lStar="96"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant98.xml b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant98.xml
new file mode 100644
index 0000000..7e5ee24
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_neutral_variant98.xml
@@ -0,0 +1,20 @@
+<?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">
+    <item android:color="@android:color/system_neutral2_600" android:lStar="98"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_expressive_icon_check.xml b/packages/SettingsLib/SettingsTheme/res/drawable/settingslib_expressive_icon_check.xml
similarity index 100%
rename from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_expressive_icon_check.xml
rename to packages/SettingsLib/SettingsTheme/res/drawable/settingslib_expressive_icon_check.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_expressive_icon_close.xml b/packages/SettingsLib/SettingsTheme/res/drawable/settingslib_expressive_icon_close.xml
similarity index 100%
rename from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_expressive_icon_close.xml
rename to packages/SettingsLib/SettingsTheme/res/drawable/settingslib_expressive_icon_close.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_expressive_switch_thumb_icon.xml b/packages/SettingsLib/SettingsTheme/res/drawable/settingslib_expressive_switch_thumb_icon.xml
similarity index 100%
rename from packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_expressive_switch_thumb_icon.xml
rename to packages/SettingsLib/SettingsTheme/res/drawable/settingslib_expressive_switch_thumb_icon.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml b/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml
index ea7baa4..2261e58 100644
--- a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml
+++ b/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml
@@ -40,7 +40,7 @@
         android:longClickable="false"
         android:maxLines="10"
         android:ellipsize="end"
-        android:textAppearance="@style/TextAppearance.TopIntroText"/>
+        android:textAppearance="@style/TextAppearance.SettingsLib.BodyLarge"/>
 
     <com.android.settingslib.widget.LinkableTextView
         android:id="@+id/settingslib_expressive_learn_more"
diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_text_frame.xml b/packages/SettingsLib/SettingsTheme/res/layout/settingslib_expressive_preference_text_frame.xml
similarity index 89%
rename from packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_text_frame.xml
rename to packages/SettingsLib/SettingsTheme/res/layout/settingslib_expressive_preference_text_frame.xml
index c837ff4..db357f8 100644
--- a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_text_frame.xml
+++ b/packages/SettingsLib/SettingsTheme/res/layout/settingslib_expressive_preference_text_frame.xml
@@ -32,8 +32,6 @@
         android:layout_gravity="start"
         android:textAlignment="viewStart"
         android:maxLines="2"
-        android:hyphenationFrequency="normalFast"
-        android:lineBreakWordStyle="phrase"
         android:textAppearance="?android:attr/textAppearanceListItem"
         android:ellipsize="marquee"/>
 
@@ -47,7 +45,5 @@
         android:textAlignment="viewStart"
         android:textAppearance="?android:attr/textAppearanceListItemSecondary"
         android:textColor="?android:attr/textColorSecondary"
-        android:maxLines="10"
-        android:hyphenationFrequency="normalFast"
-        android:lineBreakWordStyle="phrase"/>
+        android:maxLines="10"/>
 </RelativeLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_preference_category_no_title.xml b/packages/SettingsLib/SettingsTheme/res/layout/settingslib_preference_category_no_title.xml
similarity index 100%
rename from packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_preference_category_no_title.xml
rename to packages/SettingsLib/SettingsTheme/res/layout/settingslib_preference_category_no_title.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml
index 46ec62e..8873116 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml
@@ -58,4 +58,39 @@
     <color name="settingslib_colorSurface">@color/settingslib_surface_dark</color>
 
     <color name="settingslib_list_divider_color">@android:color/system_neutral1_700</color>
+
+    <color name="settingslib_materialColorPrimary">@android:color/system_accent1_200</color>
+    <color name="settingslib_materialColorOnPrimary">@android:color/system_accent1_800</color>
+    <color name="settingslib_materialColorPrimaryContainer">@android:color/system_accent1_700</color>
+    <color name="settingslib_materialColorOnPrimaryContainer">@android:color/system_accent1_100</color>
+    <color name="settingslib_materialColorPrimaryInverse">@android:color/system_accent1_600</color>
+    <color name="settingslib_materialColorSecondary">@android:color/system_accent2_200</color>
+    <color name="settingslib_materialColorOnSecondary">@android:color/system_accent2_800</color>
+    <color name="settingslib_materialColorSecondaryContainer">@android:color/system_accent2_700</color>
+    <color name="settingslib_materialColorOnSecondaryContainer">@android:color/system_accent2_100</color>
+    <color name="settingslib_materialColorTertiary">@android:color/system_accent3_200</color>
+    <color name="settingslib_materialColorOnTertiary">@android:color/system_accent3_800</color>
+    <color name="settingslib_materialColorTertiaryContainer">@android:color/system_accent3_700</color>
+    <color name="settingslib_materialColorOnTertiaryContainer">@android:color/system_accent3_100</color>
+    <color name="settingslib_materialColorError">@color/settingslib_error_200</color>
+    <color name="settingslib_materialColorOnError">@color/settingslib_error_800</color>
+    <color name="settingslib_materialColorErrorContainer">@color/settingslib_error_700</color>
+    <color name="settingslib_materialColorOnErrorContainer">@color/settingslib_error_100</color>
+    <color name="settingslib_materialColorOutline">@android:color/system_neutral2_400</color>
+    <color name="settingslib_materialColorOutlineVariant">@android:color/system_neutral2_700</color>
+    <color name="settingslib_materialColorBackground">@color/settingslib_neutral_variant6</color>
+    <color name="settingslib_materialColorOnBackground">@android:color/system_neutral1_100</color>
+    <color name="settingslib_materialColorSurface">@color/settingslib_neutral_variant6</color>
+    <color name="settingslib_materialColorOnSurface">@android:color/system_neutral1_100</color>
+    <color name="settingslib_materialColorSurfaceVariant">@android:color/system_neutral2_700</color>
+    <color name="settingslib_materialColorOnSurfaceVariant">@android:color/system_neutral2_200</color>
+    <color name="settingslib_materialColorSurfaceInverse">@android:color/system_neutral1_100</color>
+    <color name="settingslib_materialColorOnSurfaceInverse">@android:color/system_neutral1_800</color>
+    <color name="settingslib_materialColorSurfaceBright">@color/settingslib_neutral_variant24</color>
+    <color name="settingslib_materialColorSurfaceDim">@color/settingslib_neutral_variant6</color>
+    <color name="settingslib_materialColorSurfaceContainer">@color/settingslib_neutral_variant12</color>
+    <color name="settingslib_materialColorSurfaceContainerLowest">@color/settingslib_neutral_variant4</color>
+    <color name="settingslib_materialColorSurfaceContainerLow">@android:color/system_neutral2_900</color>
+    <color name="settingslib_materialColorSurfaceContainerHigh">@color/settingslib_neutral_variant17</color>
+    <color name="settingslib_materialColorSurfaceContainerHighest">@color/settingslib_neutral_variant22</color>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/values-night-v34/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-night-v34/colors.xml
index 8cfe54f..00a1f27 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-night-v34/colors.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-night-v34/colors.xml
@@ -42,4 +42,39 @@
     <color name="settingslib_text_color_primary_device_default">@android:color/system_on_surface_dark</color>
     <!--Deprecated. After sdk 35 don't use it. using materialColorOnSurfaceVariant-->
     <color name="settingslib_text_color_secondary_device_default">@android:color/system_on_surface_variant_dark</color>
+
+    <color name="settingslib_materialColorPrimary">@android:color/system_primary_dark</color>
+    <color name="settingslib_materialColorOnPrimary">@android:color/system_on_primary_dark</color>
+    <color name="settingslib_materialColorPrimaryContainer">@android:color/system_primary_container_dark</color>
+    <color name="settingslib_materialColorOnPrimaryContainer">@android:color/system_on_primary_container_dark</color>
+    <color name="settingslib_materialColorPrimaryInverse">@android:color/system_primary_light</color>
+    <color name="settingslib_materialColorSecondary">@android:color/system_secondary_dark</color>
+    <color name="settingslib_materialColorOnSecondary">@android:color/system_on_secondary_dark</color>
+    <color name="settingslib_materialColorSecondaryContainer">@android:color/system_secondary_container_dark</color>
+    <color name="settingslib_materialColorOnSecondaryContainer">@android:color/system_on_secondary_container_dark</color>
+    <color name="settingslib_materialColorTertiary">@android:color/system_tertiary_dark</color>
+    <color name="settingslib_materialColorOnTertiary">@android:color/system_on_tertiary_dark</color>
+    <color name="settingslib_materialColorTertiaryContainer">@android:color/system_tertiary_container_dark</color>
+    <color name="settingslib_materialColorOnTertiaryContainer">@android:color/system_on_tertiary_container_dark</color>
+    <color name="settingslib_materialColorError">@android:color/system_error_dark</color>
+    <color name="settingslib_materialColorOnError">@android:color/system_on_error_dark</color>
+    <color name="settingslib_materialColorErrorContainer">@android:color/system_error_container_dark</color>
+    <color name="settingslib_materialColorOnErrorContainer">@android:color/system_on_error_container_dark</color>
+    <color name="settingslib_materialColorOutline">@android:color/system_outline_dark</color>
+    <color name="settingslib_materialColorOutlineVariant">@android:color/system_outline_variant_dark</color>
+    <color name="settingslib_materialColorBackground">@android:color/system_background_dark</color>
+    <color name="settingslib_materialColorOnBackground">@android:color/system_on_background_dark</color>
+    <color name="settingslib_materialColorSurface">@android:color/system_surface_dark</color>
+    <color name="settingslib_materialColorOnSurface">@android:color/system_on_surface_dark</color>
+    <color name="settingslib_materialColorSurfaceVariant">@android:color/system_surface_variant_dark</color>
+    <color name="settingslib_materialColorOnSurfaceVariant">@android:color/system_on_surface_variant_dark</color>
+    <color name="settingslib_materialColorSurfaceInverse">@android:color/system_surface_light</color>
+    <color name="settingslib_materialColorOnSurfaceInverse">@android:color/system_on_surface_light</color>
+    <color name="settingslib_materialColorSurfaceBright">@android:color/system_surface_bright_dark</color>
+    <color name="settingslib_materialColorSurfaceDim">@android:color/system_surface_dim_dark</color>
+    <color name="settingslib_materialColorSurfaceContainer">@android:color/system_surface_container_dark</color>
+    <color name="settingslib_materialColorSurfaceContainerLow">@android:color/system_surface_container_low_dark</color>
+    <color name="settingslib_materialColorSurfaceContainerLowest">@android:color/system_surface_container_lowest_dark</color>
+    <color name="settingslib_materialColorSurfaceContainerHigh">@android:color/system_surface_container_high_dark</color>
+    <color name="settingslib_materialColorSurfaceContainerHighest">@android:color/system_surface_container_highest_dark</color>
 </resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-night-v35/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-night-v35/colors.xml
index 84a3ed6..e31e801 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-night-v35/colors.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-night-v35/colors.xml
@@ -46,37 +46,4 @@
     <color name="settingslib_colorSurfaceHeader">@color/settingslib_materialColorSurfaceVariant</color>
 
     <color name="settingslib_text_color_preference_category_title">@color/settingslib_materialColorPrimary</color>
-
-    <color name="settingslib_materialColorSurfaceContainerLowest">@android:color/system_surface_container_lowest_dark</color>
-    <color name="settingslib_materialColorOnSecondaryContainer">@android:color/system_on_secondary_container_dark</color>
-    <color name="settingslib_materialColorOnTertiaryContainer">@android:color/system_on_tertiary_container_dark</color>
-    <color name="settingslib_materialColorSurfaceContainerLow">@android:color/system_surface_container_low_dark</color>
-    <color name="settingslib_materialColorOnPrimaryContainer">@android:color/system_on_primary_container_dark</color>
-    <color name="settingslib_materialColorOnErrorContainer">@android:color/system_on_error_container_dark</color>
-    <color name="settingslib_materialColorInverseOnSurface">@android:color/system_on_surface_light</color>
-    <color name="settingslib_materialColorSecondaryContainer">@android:color/system_secondary_container_dark</color>
-    <color name="settingslib_materialColorErrorContainer">@android:color/system_error_container_dark</color>
-    <color name="settingslib_materialColorInversePrimary">@android:color/system_primary_light</color>
-    <color name="settingslib_materialColorInverseSurface">@android:color/system_surface_light</color>
-    <color name="settingslib_materialColorSurfaceVariant">@android:color/system_surface_variant_dark</color>
-    <color name="settingslib_materialColorTertiaryContainer">@android:color/system_tertiary_container_dark</color>
-    <color name="settingslib_materialColorPrimaryContainer">@android:color/system_primary_container_dark</color>
-    <color name="settingslib_materialColorOnBackground">@android:color/system_on_background_dark</color>
-    <color name="settingslib_materialColorOnSecondary">@android:color/system_on_secondary_dark</color>
-    <color name="settingslib_materialColorOnTertiary">@android:color/system_on_tertiary_dark</color>
-    <color name="settingslib_materialColorSurfaceDim">@android:color/system_surface_dim_dark</color>
-    <color name="settingslib_materialColorSurfaceBright">@android:color/system_surface_bright_dark</color>
-    <color name="settingslib_materialColorOnError">@android:color/system_on_error_dark</color>
-    <color name="settingslib_materialColorSurface">@android:color/system_surface_dark</color>
-    <color name="settingslib_materialColorSurfaceContainerHigh">@android:color/system_surface_container_high_dark</color>
-    <color name="settingslib_materialColorSurfaceContainerHighest">@android:color/system_surface_container_highest_dark</color>
-    <color name="settingslib_materialColorOnSurfaceVariant">@android:color/system_on_surface_variant_dark</color>
-    <color name="settingslib_materialColorOutline">@android:color/system_outline_dark</color>
-    <color name="settingslib_materialColorOutlineVariant">@android:color/system_outline_variant_dark</color>
-    <color name="settingslib_materialColorOnPrimary">@android:color/system_on_primary_dark</color>
-    <color name="settingslib_materialColorOnSurface">@android:color/system_on_surface_dark</color>
-    <color name="settingslib_materialColorSurfaceContainer">@android:color/system_surface_container_dark</color>
-    <color name="settingslib_materialColorPrimary">@android:color/system_primary_dark</color>
-    <color name="settingslib_materialColorSecondary">@android:color/system_secondary_dark</color>
-    <color name="settingslib_materialColorTertiary">@android:color/system_tertiary_dark</color>
 </resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-night/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-night/colors.xml
new file mode 100644
index 0000000..e57fe4f
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-night/colors.xml
@@ -0,0 +1,53 @@
+<?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>
+    <color name="settingslib_materialColorPrimary">#83D6C7</color>
+    <color name="settingslib_materialColorOnPrimary">#003730</color>
+    <color name="settingslib_materialColorPrimaryContainer">#005047</color>
+    <color name="settingslib_materialColorOnPrimaryContainer">#A1F1E2</color>
+    <color name="settingslib_materialColorPrimaryInverse">#A1F1E2</color>
+    <color name="settingslib_materialColorSecondary">#B1CCC6</color>
+    <color name="settingslib_materialColorOnSecondary">#1C342F</color>
+    <color name="settingslib_materialColorSecondaryContainer">#334C47</color>
+    <color name="settingslib_materialColorOnSecondaryContainer">#CCE8E2</color>
+    <color name="settingslib_materialColorTertiary">#ADCAE5</color>
+    <color name="settingslib_materialColorOnTertiary">#123349</color>
+    <color name="settingslib_materialColorTertiaryContainer">#2D4960</color>
+    <color name="settingslib_materialColorOnTertiaryContainer">#CEE7FF</color>
+    <color name="settingslib_materialColorError">#F2B8B5</color>
+    <color name="settingslib_materialColorOnError">#601410</color>
+    <color name="settingslib_materialColorErrorContainer">#8C1D18</color>
+    <color name="settingslib_materialColorOnErrorContainer">#F9DEDC</color>
+    <color name="settingslib_materialColorOutline">#919191</color>
+    <color name="settingslib_materialColorOutlineVariant">#474747</color>
+    <color name="settingslib_materialColorBackground">#131313</color>
+    <color name="settingslib_materialColorOnBackground">#E5E2E1</color>
+    <color name="settingslib_materialColorSurface">#131313</color>
+    <color name="settingslib_materialColorOnSurface">#E5E2E1</color>
+    <color name="settingslib_materialColorSurfaceVariant">#474747</color>
+    <color name="settingslib_materialColorOnSurfaceVariant">#C7C7C7</color>
+    <color name="settingslib_materialColorSurfaceInverse">#E5E2E1</color>
+    <color name="settingslib_materialColorOnSurfaceInverse">#303030</color>
+    <color name="settingslib_materialColorSurfaceBright">#393939</color>
+    <color name="settingslib_materialColorSurfaceDim">#131313</color>
+    <color name="settingslib_materialColorSurfaceContainer">#1F1F1F</color>
+    <color name="settingslib_materialColorSurfaceContainerLowest">#1B1B1B</color>
+    <color name="settingslib_materialColorSurfaceContainerLow">#0E0E0E</color>
+    <color name="settingslib_materialColorSurfaceContainerHigh">#2A2A2A</color>
+    <color name="settingslib_materialColorSurfaceContainerHighest">#343434</color>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml
index fef92b7..e000423 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml
@@ -92,4 +92,51 @@
     <color name="settingslib_spinner_dropdown_color">@android:color/system_neutral2_700</color>
 
     <color name="settingslib_list_divider_color">@android:color/system_neutral1_200</color>
+
+    <color name="settingslib_materialColorPrimary">@android:color/system_accent1_600</color>
+    <color name="settingslib_materialColorOnPrimary">@android:color/system_accent1_0</color>
+    <color name="settingslib_materialColorPrimaryContainer">@android:color/system_accent1_100</color>
+    <color name="settingslib_materialColorOnPrimaryContainer">@android:color/system_accent1_900</color>
+    <color name="settingslib_materialColorPrimaryInverse">@android:color/system_accent1_200</color>
+    <color name="settingslib_materialColorPrimaryFixed">@android:color/system_accent1_100</color>
+    <color name="settingslib_materialColorPrimaryFixedDim">@android:color/system_accent1_200</color>
+    <color name="settingslib_materialColorOnPrimaryFixed">@android:color/system_accent1_900</color>
+    <color name="settingslib_materialColorOnPrimaryFixedVariant">@android:color/system_accent1_700</color>
+    <color name="settingslib_materialColorSecondary">@android:color/system_accent2_600</color>
+    <color name="settingslib_materialColorOnSecondary">@android:color/system_accent2_0</color>
+    <color name="settingslib_materialColorSecondaryContainer">@android:color/system_accent2_100</color>
+    <color name="settingslib_materialColorOnSecondaryContainer">@android:color/system_accent2_900</color>
+    <color name="settingslib_materialColorSecondaryFixed">@android:color/system_accent2_100</color>
+    <color name="settingslib_materialColorSecondaryFixedDim">@android:color/system_accent2_200</color>
+    <color name="settingslib_materialColorOnSecondaryFixed">@android:color/system_accent2_900</color>
+    <color name="settingslib_materialColorOnSecondaryFixedVariant">@android:color/system_accent2_700</color>
+    <color name="settingslib_materialColorTertiary">@android:color/system_accent3_600</color>
+    <color name="settingslib_materialColorOnTertiary">@android:color/system_accent3_0</color>
+    <color name="settingslib_materialColorTertiaryContainer">@android:color/system_accent3_100</color>
+    <color name="settingslib_materialColorOnTertiaryContainer">@android:color/system_accent3_900</color>
+    <color name="settingslib_materialColorTertiaryFixed">@android:color/system_accent3_100</color>
+    <color name="settingslib_materialColorTertiaryFixedDim">@android:color/system_accent3_200</color>
+    <color name="settingslib_materialColorOnTertiaryFixed">@android:color/system_accent3_900</color>
+    <color name="settingslib_materialColorOnTertiaryFixedVariant">@android:color/system_accent3_700</color>
+    <color name="settingslib_materialColorError">@color/settingslib_error_600</color>
+    <color name="settingslib_materialColorOnError">@android:color/white</color>
+    <color name="settingslib_materialColorErrorContainer">@color/settingslib_error_100</color>
+    <color name="settingslib_materialColorOnErrorContainer">@color/settingslib_error_900</color>
+    <color name="settingslib_materialColorOutline">@android:color/system_neutral2_500</color>
+    <color name="settingslib_materialColorOutlineVariant">@android:color/system_neutral2_200</color>
+    <color name="settingslib_materialColorBackground">@android:color/white</color>
+    <color name="settingslib_materialColorOnBackground">@android:color/system_neutral1_900</color>
+    <color name="settingslib_materialColorSurface">@color/settingslib_neutral_variant98</color>
+    <color name="settingslib_materialColorOnSurface">@android:color/system_neutral1_900</color>
+    <color name="settingslib_materialColorSurfaceVariant">@android:color/system_neutral2_100</color>
+    <color name="settingslib_materialColorOnSurfaceVariant">@android:color/system_neutral2_700</color>
+    <color name="settingslib_materialColorSurfaceInverse">@android:color/system_neutral1_800</color>
+    <color name="settingslib_materialColorOnSurfaceInverse">@android:color/system_neutral1_50</color>
+    <color name="settingslib_materialColorSurfaceBright">@color/settingslib_neutral_variant98</color>
+    <color name="settingslib_materialColorSurfaceDim">@color/settingslib_neutral_variant87</color>
+    <color name="settingslib_materialColorSurfaceContainer">@color/settingslib_neutral_variant94</color>
+    <color name="settingslib_materialColorSurfaceContainerLow">@color/settingslib_neutral_variant96</color>
+    <color name="settingslib_materialColorSurfaceContainerLowest">@android:color/system_neutral2_0</color>
+    <color name="settingslib_materialColorSurfaceContainerHigh">@color/settingslib_neutral_variant92</color>
+    <color name="settingslib_materialColorSurfaceContainerHighest">@android:color/system_neutral2_100</color>
 </resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/config.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/config.xml
index 4860ad3..8993d0f 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v31/config.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v31/config.xml
@@ -17,6 +17,4 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <bool name="settingslib_config_icon_space_reserved">false</bool>
     <bool name="settingslib_config_allow_divider">false</bool>
-    <!-- Name of a font family to use for headlines in SettingsLib. -->
-    <string name="settingslib_config_headlineFontFamily" translatable="false"></string>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/styles_expressive.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/styles_expressive.xml
new file mode 100644
index 0000000..9d3d70b
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-v31/styles_expressive.xml
@@ -0,0 +1,129 @@
+<?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="SettingsLibButtonStyle.Expressive.Filled"
+        parent="@style/Widget.Material3.Button">
+        <item name="android:theme">@style/Theme.Material3.DynamicColors.DayNight</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:gravity">center</item>
+        <item name="android:minWidth">@dimen/settingslib_expressive_space_medium4</item>
+        <item name="android:minHeight">@dimen/settingslib_expressive_space_medium4</item>
+        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_extrasmall5</item>
+        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small1</item>
+        <item name="android:backgroundTint">@color/settingslib_materialColorPrimary</item>
+        <item name="android:textAppearance">@style/TextAppearance.SettingsLib.LabelLarge</item>
+        <item name="android:textColor">@color/settingslib_materialColorOnPrimary</item>
+        <item name="iconGravity">textStart</item>
+        <item name="iconTint">@color/settingslib_materialColorOnPrimary</item>
+        <item name="iconSize">@dimen/settingslib_expressive_space_small4</item>
+    </style>
+
+    <style name="SettingsLibButtonStyle.Expressive.Filled.Large">
+        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_small1</item>
+        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small4</item>
+        <item name="android:textAppearance">@style/TextAppearance.SettingsLib.TitleMedium</item>
+    </style>
+
+    <style name="SettingsLibButtonStyle.Expressive.Filled.Extra"
+        parent="@style/SettingsLibButtonStyle.Expressive.Filled.Large">
+        <item name="android:layout_width">match_parent</item>
+    </style>
+
+    <style name="SettingsLibButtonStyle.Expressive.Tonal"
+        parent="@style/Widget.Material3.Button.TonalButton">
+        <item name="android:theme">@style/Theme.Material3.DynamicColors.DayNight</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:gravity">center</item>
+        <item name="android:minWidth">@dimen/settingslib_expressive_space_medium4</item>
+        <item name="android:minHeight">@dimen/settingslib_expressive_space_medium4</item>
+        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_extrasmall5</item>
+        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small1</item>
+        <item name="android:backgroundTint">@color/settingslib_materialColorSecondaryContainer</item>
+        <item name="android:textAppearance">@style/TextAppearance.SettingsLib.LabelLarge</item>
+        <item name="android:textColor">@color/settingslib_materialColorOnSecondaryContainer</item>
+        <item name="iconGravity">textStart</item>
+        <item name="iconTint">@color/settingslib_materialColorOnSecondaryContainer</item>
+        <item name="iconSize">@dimen/settingslib_expressive_space_small4</item>
+    </style>
+
+    <style name="SettingsLibButtonStyle.Expressive.Tonal.Large">
+        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_small1</item>
+        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small4</item>
+        <item name="android:textAppearance">@style/TextAppearance.SettingsLib.TitleMedium</item>
+    </style>
+
+    <style name="SettingsLibButtonStyle.Expressive.Tonal.Extra"
+        parent="@style/SettingsLibButtonStyle.Expressive.Tonal.Large">
+        <item name="android:layout_width">match_parent</item>
+    </style>
+
+    <style name="SettingsLibButtonStyle.Expressive.Outline"
+        parent="@style/Widget.Material3.Button.OutlinedButton.Icon">
+        <item name="android:theme">@style/Theme.Material3.DynamicColors.DayNight</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:gravity">center</item>
+        <item name="android:minWidth">@dimen/settingslib_expressive_space_medium4</item>
+        <item name="android:minHeight">@dimen/settingslib_expressive_space_medium4</item>
+        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_extrasmall5</item>
+        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small1</item>
+        <item name="android:textAppearance">@style/TextAppearance.SettingsLib.LabelLarge</item>
+        <item name="android:textColor">@color/settingslib_materialColorPrimary</item>
+        <item name="iconTint">@color/settingslib_materialColorPrimary</item>
+        <item name="iconGravity">textStart</item>
+        <item name="iconSize">@dimen/settingslib_expressive_space_small4</item>
+        <item name="iconPadding">@dimen/settingslib_expressive_space_extrasmall4</item>
+        <item name="strokeColor">@color/settingslib_materialColorOutlineVariant</item>
+    </style>
+
+    <style name="SettingsLibButtonStyle.Expressive.Outline.Large">
+        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_small1</item>
+        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small4</item>
+        <item name="android:textAppearance">@style/TextAppearance.SettingsLib.TitleMedium</item>
+    </style>
+
+    <style name="SettingsLibButtonStyle.Expressive.Outline.Extra"
+        parent="@style/SettingsLibButtonStyle.Expressive.Outline.Large">
+        <item name="android:layout_width">match_parent</item>
+    </style>
+
+    <style name="SettingslibTextButtonStyle.Expressive"
+        parent="@style/Widget.Material3.Button.TextButton.Icon">
+        <item name="android:theme">@style/Theme.Material3.DynamicColors.DayNight</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textAppearance">@style/TextAppearance.SettingsLib.BodyLarge.Emphasized</item>
+        <item name="android:textColor">@color/settingslib_materialColorOnSurface</item>
+        <item name="iconTint">@null</item>
+        <item name="iconPadding">@dimen/settingslib_expressive_space_extrasmall4</item>
+        <item name="rippleColor">?android:attr/colorControlHighlight</item>
+    </style>
+
+    <style name="SettingsLibCardStyle" parent="">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginHorizontal">?android:attr/listPreferredItemPaddingStart</item>
+        <item name="android:layout_marginVertical">@dimen/settingslib_expressive_space_extrasmall4</item>
+        <item name="cardBackgroundColor">@color/settingslib_materialColorPrimary</item>
+        <item name="cardCornerRadius">@dimen/settingslib_expressive_radius_extralarge3</item>
+        <item name="cardElevation">0dp</item>
+        <item name="rippleColor">?android:attr/colorControlHighlight</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v33/styles_expressive.xml b/packages/SettingsLib/SettingsTheme/res/values-v33/styles_expressive.xml
new file mode 100644
index 0000000..74bf55a
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-v33/styles_expressive.xml
@@ -0,0 +1,306 @@
+<?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="TextAppearance.SettingsLib.DisplayLarge"
+        parent="@android:style/TextAppearance.DeviceDefault.Headline">
+        <item name="android:textSize">57sp</item>
+        <item name="android:letterSpacing">-0.00438596</item>
+        <item name="android:lineHeight">64sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.DisplayMedium"
+        parent="@android:style/TextAppearance.DeviceDefault.Headline">
+        <item name="android:textSize">45sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight">52sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.DisplaySmall"
+        parent="@android:style/TextAppearance.DeviceDefault.Headline">
+        <item name="android:textSize">36sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight">44sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.HeadlineLarge"
+        parent="@android:style/TextAppearance.DeviceDefault.Headline">
+        <item name="android:textSize">32sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight">40sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.HeadlineMedium"
+        parent="@android:style/TextAppearance.DeviceDefault.Headline">
+        <item name="android:textSize">28sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight">36sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.HeadlineSmall"
+        parent="@android:style/TextAppearance.DeviceDefault.Headline">
+        <item name="android:textSize">24sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight">32sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.TitleLarge"
+        parent="@android:style/TextAppearance.DeviceDefault.Headline">
+        <item name="android:textSize">22sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight">28sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.TitleMedium"
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        <item name="android:textSize">16sp</item>
+        <item name="android:letterSpacing">0.009375</item>
+        <item name="android:lineHeight">24sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.TitleSmall"
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        <item name="android:textSize">14sp</item>
+        <item name="android:letterSpacing">0.00714286</item>
+        <item name="android:lineHeight">20sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.LabelLarge"
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        <item name="android:textSize">14sp</item>
+        <item name="android:letterSpacing">0.00714286</item>
+        <item name="android:lineHeight">20sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.LabelMedium"
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        <item name="android:textSize">12sp</item>
+        <item name="android:letterSpacing">0.04166667</item>
+        <item name="android:lineHeight">16sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.LabelSmall"
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        <item name="android:textSize">11sp</item>
+        <item name="android:letterSpacing">0.04545455</item>
+        <item name="android:lineHeight">16sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.BodyLarge"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:textSize">16sp</item>
+        <item name="android:letterSpacing">0.03125</item>
+        <item name="android:lineHeight">24sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.BodyMedium"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:textSize">14sp</item>
+        <item name="android:letterSpacing">0.01785714</item>
+        <item name="android:lineHeight">20sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.BodySmall"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:textSize">12sp</item>
+        <item name="android:letterSpacing">0.03333333</item>
+        <item name="android:lineHeight">16sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.DisplayLarge.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+        <item name="android:textSize">57sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight">64sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.DisplayMedium.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+        <item name="android:textSize">45sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight">52sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.DisplaySmall.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+        <item name="android:textSize">36sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight">44sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.HeadlineLarge.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+        <item name="android:textSize">32sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight">40sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.HeadlineMedium.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+        <item name="android:textSize">28sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight">36sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.HeadlineSmall.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+        <item name="android:textSize">24sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight">32sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.TitleLarge.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+        <item name="android:textSize">22sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight">28sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.TitleMedium.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:textStyle">bold</item>
+        <item name="android:textSize">16sp</item>
+        <item name="android:letterSpacing">0.009375</item>
+        <item name="android:lineHeight">24sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.TitleSmall.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:textStyle">bold</item>
+        <item name="android:textSize">14sp</item>
+        <item name="android:letterSpacing">0.00714286</item>
+        <item name="android:lineHeight">20sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.LabelLarge.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:textStyle">bold</item>
+        <item name="android:textSize">14sp</item>
+        <item name="android:letterSpacing">0.00714286</item>
+        <item name="android:lineHeight">20sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.LabelMedium.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:textStyle">bold</item>
+        <item name="android:textSize">12sp</item>
+        <item name="android:letterSpacing">0.04166667</item>
+        <item name="android:lineHeight">16sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.LabelSmall.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:textStyle">bold</item>
+        <item name="android:textSize">11sp</item>
+        <item name="android:letterSpacing">0.04545455</item>
+        <item name="android:lineHeight">16sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.BodyLarge.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        <item name="android:textStyle">normal</item>
+        <item name="android:textSize">16sp</item>
+        <item name="android:letterSpacing">0.009375</item>
+        <item name="android:lineHeight">24sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.BodyMedium.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        <item name="android:textStyle">normal</item>
+        <item name="android:textSize">14sp</item>
+        <item name="android:letterSpacing">0.01785714</item>
+        <item name="android:lineHeight">20sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.BodySmall.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        <item name="android:textStyle">normal</item>
+        <item name="android:textSize">12sp</item>
+        <item name="android:letterSpacing">0.03333333</item>
+        <item name="android:lineHeight">16sp</item>
+        <item name="android:hyphenationFrequency">normalFast</item>
+        <item name="android:lineBreakWordStyle">phrase</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v34/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-v34/colors.xml
index 185ac3e..60642e6 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v34/colors.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v34/colors.xml
@@ -43,4 +43,51 @@
     <color name="settingslib_text_color_primary_device_default">@android:color/system_on_surface_light</color>
     <!--Deprecated. After sdk 35 don't use it. using materialColorOnSurfaceVariant-->
     <color name="settingslib_text_color_secondary_device_default">@android:color/system_on_surface_variant_light</color>
+
+    <color name="settingslib_materialColorPrimary">@android:color/system_primary_light</color>
+    <color name="settingslib_materialColorOnPrimary">@android:color/system_on_primary_light</color>
+    <color name="settingslib_materialColorPrimaryContainer">@android:color/system_primary_container_light</color>
+    <color name="settingslib_materialColorOnPrimaryContainer">@android:color/system_on_primary_container_light</color>
+    <color name="settingslib_materialColorPrimaryInverse">@android:color/system_primary_dark</color>
+    <color name="settingslib_materialColorPrimaryFixed">@android:color/system_primary_fixed</color>
+    <color name="settingslib_materialColorPrimaryFixedDim">@android:color/system_primary_fixed_dim</color>
+    <color name="settingslib_materialColorOnPrimaryFixed">@android:color/system_on_primary_fixed</color>
+    <color name="settingslib_materialColorOnPrimaryFixedVariant">@android:color/system_on_primary_fixed_variant</color>
+    <color name="settingslib_materialColorSecondary">@android:color/system_secondary_light</color>
+    <color name="settingslib_materialColorOnSecondary">@android:color/system_on_secondary_light</color>
+    <color name="settingslib_materialColorSecondaryContainer">@android:color/system_secondary_container_light</color>
+    <color name="settingslib_materialColorOnSecondaryContainer">@android:color/system_on_secondary_container_light</color>
+    <color name="settingslib_materialColorSecondaryFixed">@android:color/system_secondary_fixed</color>
+    <color name="settingslib_materialColorSecondaryFixedDim">@android:color/system_secondary_fixed_dim</color>
+    <color name="settingslib_materialColorOnSecondaryFixed">@android:color/system_on_secondary_fixed</color>
+    <color name="settingslib_materialColorOnSecondaryFixedVariant">@android:color/system_on_secondary_fixed_variant</color>
+    <color name="settingslib_materialColorTertiary">@android:color/system_tertiary_light</color>
+    <color name="settingslib_materialColorOnTertiary">@android:color/system_on_tertiary_light</color>
+    <color name="settingslib_materialColorTertiaryContainer">@android:color/system_tertiary_container_light</color>
+    <color name="settingslib_materialColorOnTertiaryContainer">@android:color/system_on_tertiary_container_light</color>
+    <color name="settingslib_materialColorTertiaryFixed">@android:color/system_tertiary_fixed</color>
+    <color name="settingslib_materialColorTertiaryFixedDim">@android:color/system_tertiary_fixed_dim</color>
+    <color name="settingslib_materialColorOnTertiaryFixed">@android:color/system_on_tertiary_fixed</color>
+    <color name="settingslib_materialColorOnTertiaryFixedVariant">@android:color/system_on_tertiary_fixed_variant</color>
+    <color name="settingslib_materialColorError">@android:color/system_error_light</color>
+    <color name="settingslib_materialColorOnError">@android:color/system_on_error_light</color>
+    <color name="settingslib_materialColorErrorContainer">@android:color/system_error_container_light</color>
+    <color name="settingslib_materialColorOnErrorContainer">@android:color/system_on_error_container_light</color>
+    <color name="settingslib_materialColorOutline">@android:color/system_outline_light</color>
+    <color name="settingslib_materialColorOutlineVariant">@android:color/system_outline_variant_light</color>
+    <color name="settingslib_materialColorBackground">@android:color/system_background_light</color>
+    <color name="settingslib_materialColorOnBackground">@android:color/system_on_background_light</color>
+    <color name="settingslib_materialColorSurface">@android:color/system_surface_light</color>
+    <color name="settingslib_materialColorOnSurface">@android:color/system_on_surface_light</color>
+    <color name="settingslib_materialColorSurfaceVariant">@android:color/system_surface_variant_light</color>
+    <color name="settingslib_materialColorOnSurfaceVariant">@android:color/system_on_surface_variant_light</color>
+    <color name="settingslib_materialColorSurfaceInverse">@android:color/system_surface_dark</color>
+    <color name="settingslib_materialColorOnSurfaceInverse">@android:color/system_on_surface_dark</color>
+    <color name="settingslib_materialColorSurfaceBright">@android:color/system_surface_bright_light</color>
+    <color name="settingslib_materialColorSurfaceDim">@android:color/system_surface_dim_light</color>
+    <color name="settingslib_materialColorSurfaceContainer">@android:color/system_surface_container_light</color>
+    <color name="settingslib_materialColorSurfaceContainerLow">@android:color/system_surface_container_low_light</color>
+    <color name="settingslib_materialColorSurfaceContainerLowest">@android:color/system_surface_container_lowest_light</color>
+    <color name="settingslib_materialColorSurfaceContainerHigh">@android:color/system_surface_container_high_light</color>
+    <color name="settingslib_materialColorSurfaceContainerHighest">@android:color/system_surface_container_highest_light</color>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-v35/colors.xml
index 90c19e1..b1b37b1 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v35/colors.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v35/colors.xml
@@ -54,49 +54,4 @@
     <color name="settingslib_spinner_title_color">@color/settingslib_materialColorOnPrimaryContainer</color>
     <!-- The text color of dropdown item title -->
     <color name="settingslib_spinner_dropdown_color">@color/settingslib_materialColorOnPrimaryContainer</color>
-
-    <color name="settingslib_materialColorOnSecondaryFixedVariant">@android:color/system_on_secondary_fixed_variant</color>
-    <color name="settingslib_materialColorOnTertiaryFixedVariant">@android:color/system_on_tertiary_fixed_variant</color>
-    <color name="settingslib_materialColorSurfaceContainerLowest">@android:color/system_surface_container_lowest_light</color>
-    <color name="settingslib_materialColorOnPrimaryFixedVariant">@android:color/system_on_primary_fixed_variant</color>
-    <color name="settingslib_materialColorOnSecondaryContainer">@android:color/system_on_secondary_container_light</color>
-    <color name="settingslib_materialColorOnTertiaryContainer">@android:color/system_on_tertiary_container_light</color>
-    <color name="settingslib_materialColorSurfaceContainerLow">@android:color/system_surface_container_low_light</color>
-    <color name="settingslib_materialColorOnPrimaryContainer">@android:color/system_on_primary_container_light</color>
-    <color name="settingslib_materialColorSecondaryFixedDim">@android:color/system_secondary_fixed_dim</color>
-    <color name="settingslib_materialColorOnErrorContainer">@android:color/system_on_error_container_light</color>
-    <color name="settingslib_materialColorOnSecondaryFixed">@android:color/system_on_secondary_fixed</color>
-    <color name="settingslib_materialColorInverseOnSurface">@android:color/system_on_surface_dark</color>
-    <color name="settingslib_materialColorTertiaryFixedDim">@android:color/system_tertiary_fixed_dim</color>
-    <color name="settingslib_materialColorOnTertiaryFixed">@android:color/system_on_tertiary_fixed</color>
-    <color name="settingslib_materialColorPrimaryFixedDim">@android:color/system_primary_fixed_dim</color>
-    <color name="settingslib_materialColorSecondaryContainer">@android:color/system_secondary_container_light</color>
-    <color name="settingslib_materialColorErrorContainer">@android:color/system_error_container_light</color>
-    <color name="settingslib_materialColorOnPrimaryFixed">@android:color/system_on_primary_fixed</color>
-    <color name="settingslib_materialColorInversePrimary">@android:color/system_primary_dark</color>
-    <color name="settingslib_materialColorSecondaryFixed">@android:color/system_secondary_fixed</color>
-    <color name="settingslib_materialColorInverseSurface">@android:color/system_surface_dark</color>
-    <color name="settingslib_materialColorSurfaceVariant">@android:color/system_surface_variant_light</color>
-    <color name="settingslib_materialColorTertiaryContainer">@android:color/system_tertiary_container_light</color>
-    <color name="settingslib_materialColorTertiaryFixed">@android:color/system_tertiary_fixed</color>
-    <color name="settingslib_materialColorPrimaryContainer">@android:color/system_primary_container_light</color>
-    <color name="settingslib_materialColorOnBackground">@android:color/system_on_background_light</color>
-    <color name="settingslib_materialColorPrimaryFixed">@android:color/system_primary_fixed</color>
-    <color name="settingslib_materialColorOnSecondary">@android:color/system_on_secondary_light</color>
-    <color name="settingslib_materialColorOnTertiary">@android:color/system_on_tertiary_light</color>
-    <color name="settingslib_materialColorSurfaceDim">@android:color/system_surface_dim_light</color>
-    <color name="settingslib_materialColorSurfaceBright">@android:color/system_surface_bright_light</color>
-    <color name="settingslib_materialColorOnError">@android:color/system_on_error_light</color>
-    <color name="settingslib_materialColorSurface">@android:color/system_surface_light</color>
-    <color name="settingslib_materialColorSurfaceContainerHigh">@android:color/system_surface_container_high_light</color>
-    <color name="settingslib_materialColorSurfaceContainerHighest">@android:color/system_surface_container_highest_light</color>
-    <color name="settingslib_materialColorOnSurfaceVariant">@android:color/system_on_surface_variant_light</color>
-    <color name="settingslib_materialColorOutline">@android:color/system_outline_light</color>
-    <color name="settingslib_materialColorOutlineVariant">@android:color/system_outline_variant_light</color>
-    <color name="settingslib_materialColorOnPrimary">@android:color/system_on_primary_light</color>
-    <color name="settingslib_materialColorOnSurface">@android:color/system_on_surface_light</color>
-    <color name="settingslib_materialColorSurfaceContainer">@android:color/system_surface_container_light</color>
-    <color name="settingslib_materialColorPrimary">@android:color/system_primary_light</color>
-    <color name="settingslib_materialColorSecondary">@android:color/system_secondary_light</color>
-    <color name="settingslib_materialColorTertiary">@android:color/system_tertiary_light</color>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/styles_expressive.xml b/packages/SettingsLib/SettingsTheme/res/values-v35/styles_expressive.xml
index 05a1cea..1a08568 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v35/styles_expressive.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v35/styles_expressive.xml
@@ -16,150 +16,6 @@
   -->
 
 <resources>
-    <style name="SettingsLibTextAppearance" parent="@android:style/TextAppearance.DeviceDefault">
-        <!--item name="android:fontFamily"></item-->
-        <item name="android:hyphenationFrequency">normalFast</item>
-        <item name="android:lineBreakWordStyle">phrase</item>
-    </style>
-
-    <style name="SettingsLibTextAppearance.Primary">
-        <!--item name="android:fontFamily"></item-->
-    </style>
-
-    <style name="SettingsLibTextAppearance.Primary.Display">
-        <!--item name="android:fontFamily"></item-->
-    </style>
-    <style name="SettingsLibTextAppearance.Primary.Display.Large">
-        <item name="android:textSize">57sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Primary.Display.Medium">
-        <item name="android:textSize">45sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Primary.Display.Small">
-        <item name="android:textSize">36sp</item>
-    </style>
-
-    <style name="SettingsLibTextAppearance.Primary.Headline">
-        <!--item name="android:fontFamily"></item-->
-    </style>
-    <style name="SettingsLibTextAppearance.Primary.Headline.Large">
-        <item name="android:textSize">32sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Primary.Headline.Medium">
-        <item name="android:textSize">28sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Primary.Headline.Small">
-        <item name="android:textSize">24sp</item>
-    </style>
-
-    <style name="SettingsLibTextAppearance.Primary.Title">
-        <!--item name="android:fontFamily"></item-->
-    </style>
-    <style name="SettingsLibTextAppearance.Primary.Title.Large">
-        <item name="android:textSize">22sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Primary.Title.Medium">
-        <item name="android:textSize">16sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Primary.Title.Small">
-        <item name="android:textSize">14sp</item>
-    </style>
-
-    <style name="SettingsLibTextAppearance.Primary.Label">
-        <!--item name="android:fontFamily"></item-->
-    </style>
-    <style name="SettingsLibTextAppearance.Primary.Label.Large">
-        <item name="android:textSize">14sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Primary.Label.Medium">
-        <item name="android:textSize">12sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Primary.Label.Small">
-        <item name="android:textSize">11sp</item>
-    </style>
-
-    <style name="SettingsLibTextAppearance.Primary.Body">
-        <!--item name="android:fontFamily"></item-->
-    </style>
-    <style name="SettingsLibTextAppearance.Primary.Body.Large">
-        <item name="android:textSize">16sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Primary.Body.Medium">
-        <item name="android:textSize">14sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Primary.Body.Small">
-        <item name="android:textSize">12sp</item>
-    </style>
-
-    <style name="SettingsLibTextAppearance.Emphasized">
-        <!--item name="android:fontFamily"></item-->
-    </style>
-
-    <style name="SettingsLibTextAppearance.Emphasized.Display">
-        <!--item name="android:fontFamily"></item-->
-    </style>
-    <style name="SettingsLibTextAppearance.Emphasized.Display.Large">
-        <item name="android:textSize">57sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Emphasized.Display.Medium">
-        <item name="android:textSize">45sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Emphasized.Display.Small">
-        <item name="android:textSize">36sp</item>
-    </style>
-
-    <style name="SettingsLibTextAppearance.Emphasized.Headline">
-        <!--item name="android:fontFamily"></item-->
-    </style>
-    <style name="SettingsLibTextAppearance.Emphasized.Headline.Large">
-        <item name="android:textSize">32sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Emphasized.Headline.Medium">
-        <item name="android:textSize">28sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Emphasized.Headline.Small">
-        <item name="android:textSize">24sp</item>
-    </style>
-
-    <style name="SettingsLibTextAppearance.Emphasized.Title">
-        <!--item name="android:fontFamily"></item-->
-    </style>
-    <style name="SettingsLibTextAppearance.Emphasized.Title.Large">
-        <item name="android:textSize">22sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Emphasized.Title.Medium">
-        <item name="android:textSize">16sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Emphasized.Title.Small">
-        <item name="android:textSize">14sp</item>
-    </style>
-
-    <style name="SettingsLibTextAppearance.Emphasized.Label">
-        <!--item name="android:fontFamily"></item-->
-    </style>
-    <style name="SettingsLibTextAppearance.Emphasized.Label.Large">
-        <item name="android:textSize">14sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Emphasized.Label.Medium">
-        <item name="android:textSize">12sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Emphasized.Label.Small">
-        <item name="android:textSize">11sp</item>
-    </style>
-
-    <style name="SettingsLibTextAppearance.Emphasized.Body">
-        <!--item name="android:fontFamily"></item-->
-    </style>
-    <style name="SettingsLibTextAppearance.Emphasized.Body.Large">
-        <item name="android:textSize">16sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Emphasized.Body.Medium">
-        <item name="android:textSize">14sp</item>
-    </style>
-    <style name="SettingsLibTextAppearance.Emphasized.Body.Small">
-        <item name="android:textSize">12sp</item>
-    </style>
-
     <style name="SettingslibSwitchStyle.Expressive" parent="">
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
@@ -175,122 +31,6 @@
         <item name="trackTint">@color/settingslib_expressive_color_main_switch_track</item>
     </style>
 
-    <style name="SettingsLibCardStyle" parent="">
-        <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:layout_marginHorizontal">?android:attr/listPreferredItemPaddingStart</item>
-        <item name="android:layout_marginVertical">@dimen/settingslib_expressive_space_extrasmall4</item>
-        <item name="cardBackgroundColor">@color/settingslib_materialColorPrimary</item>
-        <item name="cardCornerRadius">@dimen/settingslib_expressive_radius_extralarge3</item>
-        <item name="cardElevation">0dp</item>
-        <item name="rippleColor">?android:attr/colorControlHighlight</item>
-    </style>
-
-    <style name="SettingsLibButtonStyle.Expressive.Filled"
-        parent="@style/Widget.Material3.Button">
-        <item name="android:theme">@style/Theme.Material3.DynamicColors.DayNight</item>
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:gravity">center</item>
-        <item name="android:minWidth">@dimen/settingslib_expressive_space_medium4</item>
-        <item name="android:minHeight">@dimen/settingslib_expressive_space_medium4</item>
-        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_extrasmall5</item>
-        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small1</item>
-        <item name="android:backgroundTint">@color/settingslib_materialColorPrimary</item>
-        <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item>
-        <item name="android:textColor">@color/settingslib_materialColorOnPrimary</item>
-        <item name="android:textSize">14sp</item>
-        <item name="iconGravity">textStart</item>
-        <item name="iconTint">@color/settingslib_materialColorOnPrimary</item>
-        <item name="iconSize">@dimen/settingslib_expressive_space_small4</item>
-    </style>
-
-    <style name="SettingsLibButtonStyle.Expressive.Filled.Large">
-        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_small1</item>
-        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small4</item>
-        <item name="android:textSize">16sp</item>
-    </style>
-
-    <style name="SettingsLibButtonStyle.Expressive.Filled.Extra"
-        parent="@style/SettingsLibButtonStyle.Expressive.Filled.Large">
-        <item name="android:layout_width">match_parent</item>
-    </style>
-
-    <style name="SettingsLibButtonStyle.Expressive.Tonal"
-        parent="@style/Widget.Material3.Button.TonalButton">
-        <item name="android:theme">@style/Theme.Material3.DynamicColors.DayNight</item>
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:gravity">center</item>
-        <item name="android:minWidth">@dimen/settingslib_expressive_space_medium4</item>
-        <item name="android:minHeight">@dimen/settingslib_expressive_space_medium4</item>
-        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_extrasmall5</item>
-        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small1</item>
-        <item name="android:backgroundTint">@color/settingslib_materialColorSecondaryContainer</item>
-        <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item>
-        <item name="android:textColor">@color/settingslib_materialColorOnSecondaryContainer</item>
-        <item name="android:textSize">14sp</item>
-        <item name="iconGravity">textStart</item>
-        <item name="iconTint">@color/settingslib_materialColorOnSecondaryContainer</item>
-        <item name="iconSize">@dimen/settingslib_expressive_space_small4</item>
-    </style>
-
-    <style name="SettingsLibButtonStyle.Expressive.Tonal.Large">
-        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_small1</item>
-        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small4</item>
-        <item name="android:textSize">16sp</item>
-    </style>
-
-    <style name="SettingsLibButtonStyle.Expressive.Tonal.Extra"
-        parent="@style/SettingsLibButtonStyle.Expressive.Tonal.Large">
-        <item name="android:layout_width">match_parent</item>
-    </style>
-
-    <style name="SettingsLibButtonStyle.Expressive.Outline"
-        parent="@style/Widget.Material3.Button.OutlinedButton.Icon">
-        <item name="android:theme">@style/Theme.Material3.DynamicColors.DayNight</item>
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:gravity">center</item>
-        <item name="android:minWidth">@dimen/settingslib_expressive_space_medium4</item>
-        <item name="android:minHeight">@dimen/settingslib_expressive_space_medium4</item>
-        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_extrasmall5</item>
-        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small1</item>
-        <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item>
-        <item name="android:textColor">@color/settingslib_materialColorPrimary</item>
-        <item name="android:textSize">14sp</item>
-        <item name="iconTint">@color/settingslib_materialColorPrimary</item>
-        <item name="iconGravity">textStart</item>
-        <item name="iconSize">@dimen/settingslib_expressive_space_small4</item>
-        <item name="iconPadding">@dimen/settingslib_expressive_space_extrasmall4</item>
-        <item name="strokeColor">@color/settingslib_materialColorOutlineVariant</item>
-
-    </style>
-
-    <style name="SettingsLibButtonStyle.Expressive.Outline.Large">
-        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_small1</item>
-        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small4</item>
-        <item name="android:textSize">16sp</item>
-    </style>
-
-    <style name="SettingsLibButtonStyle.Expressive.Outline.Extra"
-        parent="@style/SettingsLibButtonStyle.Expressive.Outline.Large">
-        <item name="android:layout_width">match_parent</item>
-    </style>
-
-    <style name="SettingslibTextButtonStyle.Expressive"
-        parent="@style/Widget.Material3.Button.TextButton.Icon">
-        <item name="android:theme">@style/Theme.Material3.DynamicColors.DayNight</item>
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item>
-        <item name="android:textSize">16sp</item>
-        <item name="android:textColor">@color/settingslib_materialColorOnSurface</item>
-        <item name="iconTint">@null</item>
-        <item name="iconPadding">@dimen/settingslib_expressive_space_extrasmall4</item>
-        <item name="rippleColor">?android:attr/colorControlHighlight</item>
-    </style>
-
     <style name="EntityHeader">
         <item name="android:paddingTop">@dimen/settingslib_expressive_space_small4</item>
         <item name="android:paddingBottom">@dimen/settingslib_expressive_space_small1</item>
@@ -327,12 +67,11 @@
         <item name="android:gravity">center</item>
         <item name="android:ellipsize">marquee</item>
         <item name="android:textDirection">locale</item>
-        <item name="android:textAppearance">@style/TextAppearance.EntityHeaderTitle</item>
+        <item name="android:textAppearance">@style/TextAppearance.SettingsLib.TitleLarge.Emphasized</item>
     </style>
 
     <style name="SettingslibTextAppearance.LinkableTextStyle.Expressive"
-           parent="@android:style/TextAppearance.DeviceDefault.WindowTitle">
-        <item name="android:textSize">14sp</item>
+           parent="@style/TextAppearance.SettingsLib.LabelLarge">
         <item name="android:textColor">?android:attr/colorAccent</item>
     </style>
 
@@ -346,4 +85,14 @@
         <item name="cardElevation">0dp</item>
         <item name="rippleColor">?android:attr/colorControlHighlight</item>
     </style>
+
+    <style name="TextAppearance.SettingsLib.PreferenceTitle"
+        parent="@style/TextAppearance.SettingsLib.TitleMedium">
+        <item name="android:textColor">@color/settingslib_text_color_primary</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.PreferenceSummary"
+        parent="@style/TextAppearance.SettingsLib.BodyMedium">
+        <item name="android:textColor">@color/settingslib_text_color_secondary</item>
+    </style>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/themes_expressive.xml b/packages/SettingsLib/SettingsTheme/res/values-v35/themes_expressive.xml
index fea8739..14f214a 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v35/themes_expressive.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v35/themes_expressive.xml
@@ -18,8 +18,8 @@
 <resources>
     <style name="Theme.SettingsBase.Expressive">
         <!-- Set up Preference title text style -->
-        <!--item name="android:textAppearanceListItem">@style/TextAppearance.PreferenceTitle.SettingsLib</item-->
-        <!--item name="android:textAppearanceListItemSecondary">@style/textAppearanceListItemSecondary</item-->
+        <item name="android:textAppearanceListItem">@style/TextAppearance.SettingsLib.PreferenceTitle</item>
+        <item name="android:textAppearanceListItemSecondary">@style/TextAppearance.SettingsLib.PreferenceSummary</item>
 
         <!-- Set up  list item padding -->
         <item name="android:listPreferredItemPaddingStart">@dimen/settingslib_expressive_space_small1</item>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/attrs_expressive.xml b/packages/SettingsLib/SettingsTheme/res/values/attrs_expressive.xml
similarity index 100%
rename from packages/SettingsLib/SettingsTheme/res/values-v35/attrs_expressive.xml
rename to packages/SettingsLib/SettingsTheme/res/values/attrs_expressive.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/values/colors.xml b/packages/SettingsLib/SettingsTheme/res/values/colors.xml
new file mode 100644
index 0000000..c5c613b
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values/colors.xml
@@ -0,0 +1,79 @@
+<?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>
+    <color name="settingslib_error_0">#FFFFFF</color>
+    <color name="settingslib_error_10">#FFFBFF</color>
+    <color name="settingslib_error_50">#FFEDEA</color>
+    <color name="settingslib_error_100">#FFDAD6</color>
+    <color name="settingslib_error_200">#FFB4AB</color>
+    <color name="settingslib_error_300">#FF897D</color>
+    <color name="settingslib_error_400">#FF5449</color>
+    <color name="settingslib_error_500">#DE3730</color>
+    <color name="settingslib_error_600">#BA1A1A</color>
+    <color name="settingslib_error_700">#93000A</color>
+    <color name="settingslib_error_800">#690005</color>
+    <color name="settingslib_error_900">#410002</color>
+    <color name="settingslib_error_1000">#000000</color>
+
+    <color name="settingslib_materialColorPrimary">#006B5F</color>
+    <color name="settingslib_materialColorOnPrimary">#FFFFFF</color>
+    <color name="settingslib_materialColorPrimaryContainer">#C5EAE2</color>
+    <color name="settingslib_materialColorOnPrimaryContainer">#00201C</color>
+    <color name="settingslib_materialColorPrimaryInverse">#83D6C7</color>
+    <color name="settingslib_materialColorPrimaryFixed">#C5EAE2</color>
+    <color name="settingslib_materialColorPrimaryFixedDim">#82D5C6</color>
+    <color name="settingslib_materialColorOnPrimaryFixed">#00201C</color>
+    <color name="settingslib_materialColorOnPrimaryFixedVariant">#005047</color>
+    <color name="settingslib_materialColorSecondary">#4A635E</color>
+    <color name="settingslib_materialColorOnSecondary">#FFFFFF</color>
+    <color name="settingslib_materialColorSecondaryContainer">#CCE8E2</color>
+    <color name="settingslib_materialColorOnSecondaryContainer">#051F1B</color>
+    <color name="settingslib_materialColorSecondaryFixed">#CCE8E2</color>
+    <color name="settingslib_materialColorSecondaryFixedDim">#B1CCC6</color>
+    <color name="settingslib_materialColorOnSecondaryFixed">#051F1B</color>
+    <color name="settingslib_materialColorOnSecondaryFixedVariant">#334C47</color>
+    <color name="settingslib_materialColorTertiary">#456179</color>
+    <color name="settingslib_materialColorOnTertiary">#FFFFFF</color>
+    <color name="settingslib_materialColorTertiaryContainer">#CBE6FF</color>
+    <color name="settingslib_materialColorOnTertiaryContainer">#001E31</color>
+    <color name="settingslib_materialColorTertiaryFixed">#CBE5FF</color>
+    <color name="settingslib_materialColorTertiaryFixedDim">#ADCAE5</color>
+    <color name="settingslib_materialColorOnTertiaryFixed">#001E31</color>
+    <color name="settingslib_materialColorOnTertiaryFixedVariant">#2D4A60</color>
+    <color name="settingslib_materialColorError">#B3261E</color>
+    <color name="settingslib_materialColorOnError">#FFFFFF</color>
+    <color name="settingslib_materialColorErrorContainer">#F9DEDC</color>
+    <color name="settingslib_materialColorOnErrorContainer">#3A0A08</color>
+    <color name="settingslib_materialColorOutline">#777777</color>
+    <color name="settingslib_materialColorOutlineVariant">#C7C6C5</color>
+    <color name="settingslib_materialColorBackground">#F9FAF8</color>
+    <color name="settingslib_materialColorOnBackground">#1B1B1B</color>
+    <color name="settingslib_materialColorSurface">#F9FAF8</color>
+    <color name="settingslib_materialColorOnSurface">#1B1B1B</color>
+    <color name="settingslib_materialColorSurfaceVariant">#E3E3E3</color>
+    <color name="settingslib_materialColorOnSurfaceVariant">#474747</color>
+    <color name="settingslib_materialColorSurfaceInverse">#303030</color>
+    <color name="settingslib_materialColorOnSurfaceInverse">#F1F1F1</color>
+    <color name="settingslib_materialColorSurfaceBright">#F9FAF8</color>
+    <color name="settingslib_materialColorSurfaceDim">#DADADA</color>
+    <color name="settingslib_materialColorSurfaceContainer">#EEEEEE</color>
+    <color name="settingslib_materialColorSurfaceContainerLow">#F4F4F4</color>
+    <color name="settingslib_materialColorSurfaceContainerLowest">#FFFFFF</color>
+    <color name="settingslib_materialColorSurfaceContainerHigh">#E8E8E8</color>
+    <color name="settingslib_materialColorSurfaceContainerHighest">#E3E3E3</color>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/values/config.xml b/packages/SettingsLib/SettingsTheme/res/values/config.xml
index e73dcc0..53da491 100644
--- a/packages/SettingsLib/SettingsTheme/res/values/config.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values/config.xml
@@ -16,4 +16,7 @@
   -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <bool name="settingslib_config_icon_space_reserved">true</bool>
+
+    <!-- Name of a font family to use for headlines in SettingsLib. -->
+    <string name="settingslib_config_headlineFontFamily" translatable="false"></string>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/dimens_expressive.xml b/packages/SettingsLib/SettingsTheme/res/values/dimens_expressive.xml
similarity index 100%
rename from packages/SettingsLib/SettingsTheme/res/values-v35/dimens_expressive.xml
rename to packages/SettingsLib/SettingsTheme/res/values/dimens_expressive.xml
diff --git a/packages/SettingsLib/SettingsTheme/res/values/styles_expressive.xml b/packages/SettingsLib/SettingsTheme/res/values/styles_expressive.xml
new file mode 100644
index 0000000..f73e100
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values/styles_expressive.xml
@@ -0,0 +1,253 @@
+<?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:tools="http://schemas.android.com/tools">
+    <style name="TextAppearance.SettingsLib.DisplayLarge"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:fontFamily">@string/settingslib_config_headlineFontFamily</item>
+        <item name="android:textSize">57sp</item>
+        <item name="android:letterSpacing">-0.00438596</item>
+        <item name="android:lineHeight" tools:targetApi="28">64sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.DisplayMedium"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:fontFamily">@string/settingslib_config_headlineFontFamily</item>
+        <item name="android:textSize">45sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight" tools:targetApi="28">52sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.DisplaySmall"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:fontFamily">@string/settingslib_config_headlineFontFamily</item>
+        <item name="android:textSize">36sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight" tools:targetApi="28">44sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.HeadlineLarge"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:fontFamily">@string/settingslib_config_headlineFontFamily</item>
+        <item name="android:textSize">32sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight" tools:targetApi="28">40sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.HeadlineMedium"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:fontFamily">@string/settingslib_config_headlineFontFamily</item>
+        <item name="android:textSize">28sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight" tools:targetApi="28">36sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.HeadlineSmall"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:fontFamily">@string/settingslib_config_headlineFontFamily</item>
+        <item name="android:textSize">24sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight" tools:targetApi="28">32sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.TitleLarge"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:fontFamily">@string/settingslib_config_headlineFontFamily</item>
+        <item name="android:textSize">22sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight" tools:targetApi="28">28sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.TitleMedium"
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        <item name="android:textSize">16sp</item>
+        <item name="android:letterSpacing">0.009375</item>
+        <item name="android:lineHeight" tools:targetApi="28">24sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.TitleSmall"
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        <item name="android:textSize">14sp</item>
+        <item name="android:letterSpacing">0.00714286</item>
+        <item name="android:lineHeight" tools:targetApi="28">20sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.LabelLarge"
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        <item name="android:textSize">14sp</item>
+        <item name="android:letterSpacing">0.00714286</item>
+        <item name="android:lineHeight" tools:targetApi="28">20sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.LabelMedium"
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        <item name="android:textSize">12sp</item>
+        <item name="android:letterSpacing">0.04166667</item>
+        <item name="android:lineHeight" tools:targetApi="28">16sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.LabelSmall"
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        <item name="android:textSize">11sp</item>
+        <item name="android:letterSpacing">0.04545455</item>
+        <item name="android:lineHeight" tools:targetApi="28">16sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.BodyLarge"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:textSize">16sp</item>
+        <item name="android:letterSpacing">0.03125</item>
+        <item name="android:lineHeight" tools:targetApi="28">24sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.BodyMedium"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:textSize">14sp</item>
+        <item name="android:letterSpacing">0.01785714</item>
+        <item name="android:lineHeight" tools:targetApi="28">20sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.BodySmall"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:textSize">12sp</item>
+        <item name="android:letterSpacing">0.03333333</item>
+        <item name="android:lineHeight" tools:targetApi="28">16sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.DisplayLarge.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+        <item name="android:textSize">57sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight" tools:targetApi="28">64sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.DisplayMedium.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+        <item name="android:textSize">45sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight" tools:targetApi="28">52sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.DisplaySmall.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+        <item name="android:textSize">36sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight" tools:targetApi="28">44sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.HeadlineLarge.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+        <item name="android:textSize">32sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight" tools:targetApi="28">40sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.HeadlineMedium.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+        <item name="android:textSize">28sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight" tools:targetApi="28">36sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.HeadlineSmall.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+        <item name="android:textSize">24sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight" tools:targetApi="28">32sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.TitleLarge.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+        <item name="android:textSize">22sp</item>
+        <item name="android:letterSpacing">0</item>
+        <item name="android:lineHeight" tools:targetApi="28">28sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.TitleMedium.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:textStyle">bold</item>
+        <item name="android:textSize">16sp</item>
+        <item name="android:letterSpacing">0.009375</item>
+        <item name="android:lineHeight" tools:targetApi="28">24sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.TitleSmall.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:textStyle">bold</item>
+        <item name="android:textSize">14sp</item>
+        <item name="android:letterSpacing">0.00714286</item>
+        <item name="android:lineHeight" tools:targetApi="28">20sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.LabelLarge.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:textStyle">bold</item>
+        <item name="android:textSize">14sp</item>
+        <item name="android:letterSpacing">0.00714286</item>
+        <item name="android:lineHeight" tools:targetApi="28">20sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.LabelMedium.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:textStyle">bold</item>
+        <item name="android:textSize">12sp</item>
+        <item name="android:letterSpacing">0.04166667</item>
+        <item name="android:lineHeight" tools:targetApi="28">16sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.LabelSmall.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault">
+        <item name="android:textStyle">bold</item>
+        <item name="android:textSize">11sp</item>
+        <item name="android:letterSpacing">0.04545455</item>
+        <item name="android:lineHeight" tools:targetApi="28">16sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+
+    <style name="TextAppearance.SettingsLib.BodyLarge.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        <item name="android:textStyle">normal</item>
+        <item name="android:textSize">16sp</item>
+        <item name="android:letterSpacing">0.009375</item>
+        <item name="android:lineHeight" tools:targetApi="28">24sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.BodyMedium.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        <item name="android:textStyle">normal</item>
+        <item name="android:textSize">14sp</item>
+        <item name="android:letterSpacing">0.01785714</item>
+        <item name="android:lineHeight" tools:targetApi="28">20sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+    <style name="TextAppearance.SettingsLib.BodySmall.Emphasized"
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        <item name="android:textStyle">normal</item>
+        <item name="android:textSize">12sp</item>
+        <item name="android:letterSpacing">0.03333333</item>
+        <item name="android:lineHeight" tools:targetApi="28">16sp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/Spa/build.gradle.kts b/packages/SettingsLib/Spa/build.gradle.kts
index 02e1904..cf695d0 100644
--- a/packages/SettingsLib/Spa/build.gradle.kts
+++ b/packages/SettingsLib/Spa/build.gradle.kts
@@ -14,14 +14,13 @@
  * limitations under the License.
  */
 
-import com.android.build.api.dsl.CommonExtension
 import com.android.build.gradle.BaseExtension
 import com.android.build.gradle.api.AndroidBasePlugin
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 
 plugins {
     alias(libs.plugins.android.application) apply false
     alias(libs.plugins.android.library) apply false
+    alias(libs.plugins.compose.compiler) apply false
     alias(libs.plugins.kotlin.android) apply false
 }
 
@@ -51,23 +50,4 @@
             }
         }
     }
-
-    afterEvaluate {
-        plugins.withType<AndroidBasePlugin> {
-            the(CommonExtension::class).apply {
-                if (buildFeatures.compose == true) {
-                    composeOptions {
-                        kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get()
-                    }
-                }
-            }
-        }
-    }
-
-    tasks.withType<KotlinCompile> {
-        kotlinOptions {
-            jvmTarget = libs.versions.jvm.get()
-            freeCompilerArgs = listOf("-Xjvm-default=all")
-        }
-    }
 }
diff --git a/packages/SettingsLib/Spa/gallery/build.gradle.kts b/packages/SettingsLib/Spa/gallery/build.gradle.kts
index a1151a5..19aa710 100644
--- a/packages/SettingsLib/Spa/gallery/build.gradle.kts
+++ b/packages/SettingsLib/Spa/gallery/build.gradle.kts
@@ -16,6 +16,7 @@
 
 plugins {
     alias(libs.plugins.android.application)
+    alias(libs.plugins.compose.compiler)
     alias(libs.plugins.kotlin.android)
 }
 
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageProvider.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageProvider.kt
index f7649b9..17f9965 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageProvider.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageProvider.kt
@@ -20,11 +20,13 @@
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.outlined.DisabledByDefault
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.IntState
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.produceState
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.tooling.preview.Preview
@@ -33,8 +35,11 @@
 import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.theme.SettingsTheme
 import com.android.settingslib.spa.gallery.R
+import com.android.settingslib.spa.widget.preference.ListPreferenceModel
+import com.android.settingslib.spa.widget.preference.ListPreferenceOption
 import com.android.settingslib.spa.widget.preference.Preference
 import com.android.settingslib.spa.widget.preference.PreferenceModel
+import com.android.settingslib.spa.widget.preference.RadioPreferences
 import com.android.settingslib.spa.widget.scaffold.RegularScaffold
 import com.android.settingslib.spa.widget.ui.Category
 import com.android.settingslib.spa.widget.ui.SettingsIcon
@@ -103,6 +108,22 @@
                     override val summary = { ticks.toString() }
                 })
             }
+            val selectedId = rememberSaveable { mutableIntStateOf(0) }
+            RadioPreferences(
+                object : ListPreferenceModel {
+                    override val title: String = "RadioPreferences"
+                    override val options: List<ListPreferenceOption> =
+                        listOf(
+                            ListPreferenceOption(id = 0, text = "option1"),
+                            ListPreferenceOption(id = 1, text = "option2"),
+                            ListPreferenceOption(id = 2, text = "option3"),
+                        )
+                    override val selectedId: IntState = selectedId
+                    override val onIdSelected: (Int) -> Unit = {
+                        selectedId.intValue = it
+                    }
+                }
+            )
         }
     }
 
diff --git a/packages/SettingsLib/Spa/gradle/libs.versions.toml b/packages/SettingsLib/Spa/gradle/libs.versions.toml
index 74811d3..04ef96a 100644
--- a/packages/SettingsLib/Spa/gradle/libs.versions.toml
+++ b/packages/SettingsLib/Spa/gradle/libs.versions.toml
@@ -15,12 +15,11 @@
 #
 
 [versions]
-agp = "8.7.2"
-compose-compiler = "1.5.11"
+agp = "8.7.3"
 dexmaker-mockito = "2.28.3"
 jvm = "17"
-kotlin = "1.9.23"
-truth = "1.1.5"
+kotlin = "2.0.21"
+truth = "1.4.4"
 
 [libraries]
 dexmaker-mockito = { module = "com.linkedin.dexmaker:dexmaker-mockito", version.ref = "dexmaker-mockito" }
@@ -29,4 +28,5 @@
 [plugins]
 android-application = { id = "com.android.application", version.ref = "agp" }
 android-library = { id = "com.android.library", version.ref = "agp" }
+compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
 kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
diff --git a/packages/SettingsLib/Spa/spa/build.gradle.kts b/packages/SettingsLib/Spa/spa/build.gradle.kts
index 1f32ad6..a0bbb0c 100644
--- a/packages/SettingsLib/Spa/spa/build.gradle.kts
+++ b/packages/SettingsLib/Spa/spa/build.gradle.kts
@@ -16,6 +16,7 @@
 
 plugins {
     alias(libs.plugins.android.library)
+    alias(libs.plugins.compose.compiler)
     alias(libs.plugins.kotlin.android)
     jacoco
 }
@@ -41,9 +42,6 @@
             manifest.srcFile("../tests/AndroidManifest.xml")
         }
     }
-    buildFeatures {
-        compose = true
-    }
     buildTypes {
         getByName("debug") {
             enableAndroidTestCoverage = true
@@ -63,7 +61,7 @@
     api("androidx.lifecycle:lifecycle-runtime-compose")
     api("androidx.navigation:navigation-compose:2.9.0-alpha03")
     api("com.github.PhilJay:MPAndroidChart:v3.1.0-alpha")
-    api("com.google.android.material:material:1.12.0")
+    api("com.google.android.material:material:1.13.0-alpha08")
     debugApi("androidx.compose.ui:ui-tooling:$jetpackComposeVersion")
     implementation("com.airbnb.android:lottie-compose:6.4.0")
 
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/RadioPreferences.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/RadioPreferences.kt
index 8300ce8..ec94df0 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/RadioPreferences.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/RadioPreferences.kt
@@ -16,28 +16,34 @@
 
 package com.android.settingslib.spa.widget.preference
 
-import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.heightIn
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.selection.selectable
 import androidx.compose.foundation.selection.selectableGroup
+import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.RadioButton
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.IntState
+import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.tooling.preview.Preview
+import com.android.settingslib.spa.framework.compose.thenIf
 import com.android.settingslib.spa.framework.theme.SettingsDimension
-import com.android.settingslib.spa.widget.ui.CategoryTitle
+import com.android.settingslib.spa.framework.theme.isSpaExpressiveEnabled
+import com.android.settingslib.spa.widget.ui.Category
 import com.android.settingslib.spa.widget.ui.SettingsListItem
 
 @Composable
 fun RadioPreferences(model: ListPreferenceModel) {
-    CategoryTitle(title = model.title)
-    Spacer(modifier = Modifier.width(SettingsDimension.itemDividerHeight))
-    Column(modifier = Modifier.selectableGroup()) {
+    Category(modifier = Modifier.selectableGroup(), title = model.title) {
         for (option in model.options) {
             Radio2(option, model.selectedId.intValue, model.enabled()) {
                 model.onIdSelected(it)
@@ -54,20 +60,52 @@
     onIdSelected: (id: Int) -> Unit,
 ) {
     val selected = option.id == selectedId
+    val surfaceBright = MaterialTheme.colorScheme.surfaceBright
     Row(
-        modifier = Modifier
-            .fillMaxWidth()
-            .selectable(
-                selected = selected,
-                enabled = enabled,
-                onClick = { onIdSelected(option.id) },
-                role = Role.RadioButton,
-            )
-            .padding(SettingsDimension.dialogItemPadding),
+        modifier =
+            Modifier.fillMaxWidth()
+                .thenIf(isSpaExpressiveEnabled) {
+                    Modifier.heightIn(min = SettingsDimension.preferenceMinHeight)
+                        .background(surfaceBright)
+                }
+                .selectable(
+                    selected = selected,
+                    enabled = enabled,
+                    onClick = { onIdSelected(option.id) },
+                    role = Role.RadioButton,
+                )
+                .then(
+                    if (isSpaExpressiveEnabled) Modifier.padding(SettingsDimension.itemPadding)
+                    else Modifier.padding(SettingsDimension.dialogItemPadding)
+                ),
         verticalAlignment = Alignment.CenterVertically,
     ) {
         RadioButton(selected = selected, onClick = null, enabled = enabled)
-        Spacer(modifier = Modifier.width(SettingsDimension.itemDividerHeight))
+        Spacer(
+            modifier =
+                Modifier.width(
+                    if (isSpaExpressiveEnabled) SettingsDimension.paddingExtraSmall6
+                    else SettingsDimension.itemDividerHeight
+                )
+        )
         SettingsListItem(text = option.text, enabled = enabled)
     }
-}
\ No newline at end of file
+}
+
+@Preview
+@Composable
+private fun RadioPreferencePreview() {
+    RadioPreferences(
+        object : ListPreferenceModel {
+            override val title: String = "Title"
+            override val options: List<ListPreferenceOption> =
+                listOf(
+                    ListPreferenceOption(id = 0, text = "option1"),
+                    ListPreferenceOption(id = 1, text = "option2"),
+                    ListPreferenceOption(id = 2, text = "option3"),
+                )
+            override val selectedId: IntState = remember { mutableIntStateOf(0) }
+            override val onIdSelected: (Int) -> Unit = {}
+        }
+    )
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt
index 96d2abb..62bc00a 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt
@@ -76,7 +76,7 @@
  * visually separates groups of items.
  */
 @Composable
-fun Category(title: String? = null, content: @Composable ColumnScope.() -> Unit) {
+fun Category(title: String? = null, modifier: Modifier = Modifier, content: @Composable ColumnScope.() -> Unit) {
     var displayTitle by remember { mutableStateOf(false) }
     Column(
         modifier =
@@ -90,7 +90,7 @@
         if (title != null && displayTitle) CategoryTitle(title = title)
         Column(
             modifier =
-                Modifier.onGloballyPositioned { coordinates ->
+                modifier.onGloballyPositioned { coordinates ->
                         displayTitle = coordinates.size.height > 0
                     }
                     .then(
@@ -162,7 +162,7 @@
 @Composable
 private fun CategoryPreview() {
     SettingsTheme {
-        Category("Appearance") {
+        Category(title = "Appearance") {
             Preference(
                 object : PreferenceModel {
                     override val title = "Title"
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/RadioPreferencesTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/RadioPreferencesTest.kt
index 2f98b02..d187017 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/RadioPreferencesTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/RadioPreferencesTest.kt
@@ -43,7 +43,9 @@
             RadioPreferences(remember {
                 object : ListPreferenceModel {
                     override val title = TITLE
-                    override val options = emptyList<ListPreferenceOption>()
+                    override val options = listOf(
+                        ListPreferenceOption(id = 1, text = "A")
+                    )
                     override val selectedId = mutableIntStateOf(0)
                     override val onIdSelected: (Int) -> Unit = {}
                 }
diff --git a/packages/SettingsLib/Spa/testutils/build.gradle.kts b/packages/SettingsLib/Spa/testutils/build.gradle.kts
index cce8235..7dbd320 100644
--- a/packages/SettingsLib/Spa/testutils/build.gradle.kts
+++ b/packages/SettingsLib/Spa/testutils/build.gradle.kts
@@ -16,6 +16,7 @@
 
 plugins {
     alias(libs.plugins.android.library)
+    alias(libs.plugins.compose.compiler)
     alias(libs.plugins.kotlin.android)
 }
 
@@ -30,9 +31,6 @@
             manifest.srcFile("AndroidManifest.xml")
         }
     }
-    buildFeatures {
-        compose = true
-    }
 }
 
 dependencies {
diff --git a/packages/SettingsLib/StatusBannerPreference/res/layout/settingslib_expressive_preference_statusbanner.xml b/packages/SettingsLib/StatusBannerPreference/res/layout/settingslib_expressive_preference_statusbanner.xml
index 9a3e5b9..083b862 100644
--- a/packages/SettingsLib/StatusBannerPreference/res/layout/settingslib_expressive_preference_statusbanner.xml
+++ b/packages/SettingsLib/StatusBannerPreference/res/layout/settingslib_expressive_preference_statusbanner.xml
@@ -72,7 +72,7 @@
                     android:layout_height="wrap_content"
                     android:hyphenationFrequency="normalFast"
                     android:lineBreakWordStyle="phrase"
-                    android:textAppearance="@style/SettingsLibTextAppearance.Emphasized.Title.Large"/>
+                    android:textAppearance="@style/TextAppearance.SettingsLib.TitleLarge.Emphasized"/>
 
                 <TextView
                     android:id="@android:id/summary"
@@ -81,7 +81,7 @@
                     android:hyphenationFrequency="normalFast"
                     android:lineBreakWordStyle="phrase"
                     android:maxLines="3"
-                    android:textAppearance="@style/SettingsLibTextAppearance.Primary.Body.Medium"/>
+                    android:textAppearance="@style/TextAppearance.SettingsLib.BodyMedium"/>
             </LinearLayout>
         </LinearLayout>
 
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index ae04ca1..ac436ad 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -737,7 +737,7 @@
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Verander uitvoer"</string>
     <string name="back_navigation_animation" msgid="8105467568421689484">"Voorspellingteruggebaaranimasies"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Aktiveer stelselanimasies vir voorspellingteruggebaar."</string>
-    <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Hierdie instelling aktiveer stelselanimasies vir voorspellinggebaaranimasie. Dit vereis dat enableOnBackInvokedCallback per program op waar gestel word in die manifeslêer."</string>
+    <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Hierdie instelling aktiveer stelselanimasies vir voorspellinggebaaranimasie. Dit vereis dat enableOnBackInvokedCallback per app op waar gestel word in die manifeslêer."</string>
     <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="not_specified" msgid="5423502443185110328">"Nie gespesifiseer nie"</string>
     <string name="neuter" msgid="2075249330106127310">"Neutrum"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 690add8..a85d0cc 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -638,7 +638,7 @@
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"ಈಗ ಬಳಕೆದಾರರನ್ನು ಸೆಟ್ ಮಾಡಬೇಕೆ?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"ಸಾಧನವನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು ಮತ್ತು ಅದರ ಸ್ಥಳವನ್ನು ಹೊಂದಿಸಲು ವ್ಯಕ್ತಿಯು ಲಭ್ಯವಿದ್ದಾರೆಯೇ ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"ಇದೀಗ ಪ್ರೊಫೈಲ್‌ ಅನ್ನು ಹೊಂದಿಸುವುದೇ?"</string>
-    <string name="user_setup_button_setup_now" msgid="1708269547187760639">"ಇದೀಗ ಹೊಂದಿಸಿ"</string>
+    <string name="user_setup_button_setup_now" msgid="1708269547187760639">"ಇದೀಗ ಸೆಟ್ ಮಾಡಿ"</string>
     <string name="user_setup_button_setup_later" msgid="8712980133555493516">"ಈಗಲೇ ಬೇಡ"</string>
     <string name="user_add_user_type_title" msgid="551279664052914497">"ಸೇರಿಸಿ"</string>
     <string name="user_new_user_name" msgid="60979820612818840">"ಹೊಸ ಬಳಕೆದಾರರು"</string>
@@ -646,7 +646,7 @@
     <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_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>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/AmbientVolumeController.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/AmbientVolumeController.java
new file mode 100644
index 0000000..7f0c126
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/AmbientVolumeController.java
@@ -0,0 +1,415 @@
+/*
+ * 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.bluetooth;
+
+import static android.bluetooth.AudioInputControl.MUTE_DISABLED;
+import static android.bluetooth.AudioInputControl.MUTE_MUTED;
+import static android.bluetooth.AudioInputControl.MUTE_NOT_MUTED;
+
+import static com.android.settingslib.bluetooth.HearingDeviceLocalDataManager.Data.INVALID_VOLUME;
+
+import android.bluetooth.AudioInputControl;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * AmbientVolumeController manages the {@link AudioInputControl}s of
+ * {@link AudioInputControl#AUDIO_INPUT_TYPE_AMBIENT} on the remote device.
+ */
+public class AmbientVolumeController implements LocalBluetoothProfileManager.ServiceListener {
+
+    private static final boolean DEBUG = true;
+    private static final String TAG = "AmbientController";
+
+    private final LocalBluetoothProfileManager mProfileManager;
+    private final VolumeControlProfile mVolumeControlProfile;
+    private final Map<BluetoothDevice, List<AudioInputControl>> mDeviceAmbientControlsMap =
+            new ArrayMap<>();
+    private final Map<BluetoothDevice, AmbientCallback> mDeviceCallbackMap = new ArrayMap<>();
+    final Map<BluetoothDevice, RemoteAmbientState> mDeviceAmbientStateMap =
+            new ArrayMap<>();
+    @Nullable
+    private final AmbientVolumeControlCallback mCallback;
+
+    public AmbientVolumeController(
+            @NonNull LocalBluetoothProfileManager profileManager,
+            @Nullable AmbientVolumeControlCallback callback) {
+        mProfileManager = profileManager;
+        mVolumeControlProfile = profileManager.getVolumeControlProfile();
+        if (mVolumeControlProfile != null && !mVolumeControlProfile.isProfileReady()) {
+            mProfileManager.addServiceListener(this);
+        }
+        mCallback = callback;
+    }
+
+    @Override
+    public void onServiceConnected() {
+        if (mVolumeControlProfile != null && mVolumeControlProfile.isProfileReady()) {
+            mProfileManager.removeServiceListener(this);
+            if (mCallback != null) {
+                mCallback.onVolumeControlServiceConnected();
+            }
+        }
+    }
+
+    @Override
+    public void onServiceDisconnected() {
+        // Do nothing
+    }
+
+    /**
+     * Registers the same {@link AmbientCallback} on all ambient control points of the remote
+     * device. The {@link AmbientCallback} will pass the event to registered
+     * {@link AmbientVolumeControlCallback} if exists.
+     *
+     * @param executor the executor to run the callback
+     * @param device the remote device
+     */
+    public void registerCallback(@NonNull Executor executor, @NonNull BluetoothDevice device) {
+        AmbientCallback ambientCallback = new AmbientCallback(device, mCallback);
+        synchronized (mDeviceCallbackMap) {
+            mDeviceCallbackMap.put(device, ambientCallback);
+        }
+
+        // register callback on all ambient input control points of this device
+        List<AudioInputControl> controls = getAmbientControls(device);
+        controls.forEach((control) -> {
+            try {
+                control.registerCallback(executor, ambientCallback);
+            } catch (IllegalArgumentException e) {
+                // The callback was already registered
+                Log.i(TAG, "Skip registering the callback, " + e.getMessage());
+            }
+        });
+    }
+
+    /**
+     * Unregisters the {@link AmbientCallback} on all ambient control points of the remote
+     * device which is previously registered with {@link #registerCallback}.
+     *
+     * @param device the remote device
+     */
+    public void unregisterCallback(@NonNull BluetoothDevice device) {
+        AmbientCallback ambientCallback;
+        synchronized (mDeviceCallbackMap) {
+            ambientCallback = mDeviceCallbackMap.remove(device);
+        }
+        if (ambientCallback == null) {
+            // callback not found, no need to unregister
+            return;
+        }
+
+        // unregister callback on all ambient input control points of this device
+        List<AudioInputControl> controls = getAmbientControls(device);
+        controls.forEach(control -> {
+            try {
+                control.unregisterCallback(ambientCallback);
+            } catch (IllegalArgumentException e) {
+                // The callback was never registered or was already unregistered
+                Log.i(TAG, "Skip unregistering the callback, " + e.getMessage());
+            }
+        });
+    }
+
+    /**
+     * Gets the gain setting max value from first ambient control point of the remote device.
+     *
+     * @param device the remote device
+     */
+    public int getAmbientMax(@NonNull BluetoothDevice device) {
+        List<AudioInputControl> ambientControls = getAmbientControls(device);
+        int value = INVALID_VOLUME;
+        if (!ambientControls.isEmpty()) {
+            value = ambientControls.getFirst().getGainSettingMax();
+        }
+        return value;
+    }
+
+    /**
+     * Gets the gain setting min value from first ambient control point of the remote device.
+     *
+     * @param device the remote device
+     */
+    public int getAmbientMin(@NonNull BluetoothDevice device) {
+        List<AudioInputControl> ambientControls = getAmbientControls(device);
+        int value = INVALID_VOLUME;
+        if (!ambientControls.isEmpty()) {
+            value = ambientControls.getFirst().getGainSettingMin();
+        }
+        return value;
+    }
+
+    /**
+     * Gets the latest values in {@link RemoteAmbientState}.
+     *
+     * @param device the remote device
+     * @return the {@link RemoteAmbientState} represents current remote ambient control point state
+     */
+    @Nullable
+    public RemoteAmbientState refreshAmbientState(@Nullable BluetoothDevice device) {
+        if (device == null || !device.isConnected()) {
+            return null;
+        }
+        int gainSetting = getAmbient(device);
+        int mute = getMute(device);
+        return new RemoteAmbientState(gainSetting, mute);
+    }
+
+    /**
+     * Gets the gain setting value from first ambient control point of the remote device and
+     * stores it in cached {@link RemoteAmbientState}.
+     *
+     * When any audio input point receives {@link AmbientCallback#onGainSettingChanged(int)}
+     * callback, only the changed value which is different from the value stored in the cached
+     * state will be notified to the {@link AmbientVolumeControlCallback} of this controller.
+     *
+     * @param device the remote device
+     */
+    public int getAmbient(@NonNull BluetoothDevice device) {
+        List<AudioInputControl> ambientControls = getAmbientControls(device);
+        int value = INVALID_VOLUME;
+        if (!ambientControls.isEmpty()) {
+            synchronized (mDeviceAmbientStateMap) {
+                value = ambientControls.getFirst().getGainSetting();
+                RemoteAmbientState state = mDeviceAmbientStateMap.getOrDefault(device,
+                        new RemoteAmbientState(INVALID_VOLUME, MUTE_DISABLED));
+                RemoteAmbientState updatedState = new RemoteAmbientState(value, state.mute);
+                mDeviceAmbientStateMap.put(device, updatedState);
+            }
+        }
+        return value;
+    }
+
+    /**
+     * Sets the gain setting value to all ambient control points of the remote device.
+     *
+     * @param device the remote device
+     * @param value the gain setting value to be updated
+     */
+    public void setAmbient(@NonNull BluetoothDevice device, int value) {
+        if (DEBUG) {
+            Log.d(TAG, "setAmbient, value:" + value + ", device:" + device);
+        }
+        List<AudioInputControl> ambientControls = getAmbientControls(device);
+        ambientControls.forEach(control -> control.setGainSetting(value));
+    }
+
+    /**
+     * Gets the mute state from first ambient control point of the remote device and
+     * stores it in cached {@link RemoteAmbientState}. The value will be one of
+     * {@link AudioInputControl.Mute}.
+     *
+     * When any audio input point receives {@link AmbientCallback#onMuteChanged(int)} callback,
+     * only the changed value which is different from the value stored in the cached state will
+     * be notified to the {@link AmbientVolumeControlCallback} of this controller.
+     *
+     * @param device the remote device
+     */
+    public int getMute(@NonNull BluetoothDevice device) {
+        List<AudioInputControl> ambientControls = getAmbientControls(device);
+        int value = MUTE_DISABLED;
+        if (!ambientControls.isEmpty()) {
+            synchronized (mDeviceAmbientStateMap) {
+                value = ambientControls.getFirst().getMute();
+                RemoteAmbientState state = mDeviceAmbientStateMap.getOrDefault(device,
+                        new RemoteAmbientState(INVALID_VOLUME, MUTE_DISABLED));
+                RemoteAmbientState updatedState = new RemoteAmbientState(state.gainSetting, value);
+                mDeviceAmbientStateMap.put(device, updatedState);
+            }
+        }
+        return value;
+    }
+
+    /**
+     * Sets the mute state to all ambient control points of the remote device.
+     *
+     * @param device the remote device
+     * @param muted the mute state to be updated
+     */
+    public void setMuted(@NonNull BluetoothDevice device, boolean muted) {
+        if (DEBUG) {
+            Log.d(TAG, "setMuted, muted:" + muted + ", device:" + device);
+        }
+        List<AudioInputControl> ambientControls = getAmbientControls(device);
+        ambientControls.forEach(control -> {
+            try {
+                control.setMute(muted ? MUTE_MUTED : MUTE_NOT_MUTED);
+            } catch (IllegalStateException e) {
+                // Sometimes remote will throw this exception due to initialization not done
+                // yet. Catch it to prevent crashes on UI.
+                Log.w(TAG, "Remote mute state is currently disabled.");
+            }
+        });
+    }
+
+    /**
+     * Checks if there's any valid ambient control point exists on the remote device
+     *
+     * @param device the remote device
+     */
+    public boolean isAmbientControlAvailable(@NonNull BluetoothDevice device) {
+        final boolean hasAmbientControlPoint = !getAmbientControls(device).isEmpty();
+        final boolean connectedToVcp = mVolumeControlProfile.getConnectionStatus(device)
+                == BluetoothProfile.STATE_CONNECTED;
+        return hasAmbientControlPoint && connectedToVcp;
+    }
+
+    @NonNull
+    private List<AudioInputControl> getAmbientControls(@NonNull BluetoothDevice device) {
+        if (mVolumeControlProfile == null) {
+            return Collections.emptyList();
+        }
+        synchronized (mDeviceAmbientControlsMap) {
+            if (mDeviceAmbientControlsMap.containsKey(device)) {
+                return mDeviceAmbientControlsMap.get(device);
+            }
+            List<AudioInputControl> ambientControls =
+                    mVolumeControlProfile.getAudioInputControlServices(device).stream().filter(
+                            this::isValidAmbientControl).toList();
+            if (!ambientControls.isEmpty()) {
+                mDeviceAmbientControlsMap.put(device, ambientControls);
+            }
+            return ambientControls;
+        }
+    }
+
+    private boolean isValidAmbientControl(AudioInputControl control) {
+        boolean isAmbientControl =
+                control.getAudioInputType() == AudioInputControl.AUDIO_INPUT_TYPE_AMBIENT;
+        boolean isManual = control.getGainMode() == AudioInputControl.GAIN_MODE_MANUAL
+                || control.getGainMode() == AudioInputControl.GAIN_MODE_MANUAL_ONLY;
+        boolean isActive =
+                control.getAudioInputStatus() == AudioInputControl.AUDIO_INPUT_STATUS_ACTIVE;
+
+        return isAmbientControl && isManual && isActive;
+    }
+
+    /**
+     * Callback providing information about the status and received events of
+     * {@link AmbientVolumeController}.
+     */
+    public interface AmbientVolumeControlCallback {
+
+        /** This method is called when the Volume Control Service is connected */
+        default void onVolumeControlServiceConnected() {
+        }
+
+        /**
+         * This method is called when one of the remote device's ambient control point's gain
+         * settings value is changed.
+         *
+         * @param device the remote device
+         * @param gainSettings the new gain setting value
+         */
+        default void onAmbientChanged(@NonNull BluetoothDevice device, int gainSettings) {
+        }
+
+        /**
+         * This method is called when one of the remote device's ambient control point's mute
+         * state is changed.
+         *
+         * @param device the remote device
+         * @param mute the new mute state
+         */
+        default void onMuteChanged(@NonNull BluetoothDevice device, int mute) {
+        }
+
+        /**
+         * This method is called when any command to the remote device's ambient control point
+         * is failed.
+         *
+         * @param device the remote device.
+         */
+        default void onCommandFailed(@NonNull BluetoothDevice device) {
+        }
+    }
+
+    /**
+     * A wrapper callback that will pass {@link AudioInputControl.AudioInputCallback} with extra
+     * device information to {@link AmbientVolumeControlCallback}.
+     */
+    class AmbientCallback implements AudioInputControl.AudioInputCallback {
+
+        private final BluetoothDevice mDevice;
+        private final AmbientVolumeControlCallback mCallback;
+
+        AmbientCallback(@NonNull BluetoothDevice device,
+                @Nullable AmbientVolumeControlCallback callback) {
+            mDevice = device;
+            mCallback = callback;
+        }
+
+        @Override
+        public void onGainSettingChanged(int gainSetting) {
+            if (mCallback != null) {
+                synchronized (mDeviceAmbientStateMap) {
+                    RemoteAmbientState previousState = mDeviceAmbientStateMap.get(mDevice);
+                    if (previousState.gainSetting != gainSetting) {
+                        mCallback.onAmbientChanged(mDevice, gainSetting);
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void onSetGainSettingFailed() {
+            Log.w(TAG, "onSetGainSettingFailed, device=" + mDevice);
+            if (mCallback != null) {
+                mCallback.onCommandFailed(mDevice);
+            }
+        }
+
+        @Override
+        public void onMuteChanged(int mute) {
+            if (mCallback != null) {
+                synchronized (mDeviceAmbientStateMap) {
+                    RemoteAmbientState previousState = mDeviceAmbientStateMap.get(mDevice);
+                    if (previousState.mute != mute) {
+                        mCallback.onMuteChanged(mDevice, mute);
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void onSetMuteFailed() {
+            Log.w(TAG, "onSetMuteFailed, device=" + mDevice);
+            if (mCallback != null) {
+                mCallback.onCommandFailed(mDevice);
+            }
+        }
+    }
+
+    public record RemoteAmbientState(int gainSetting, int mute) {
+        public boolean isMutable() {
+            return mute != MUTE_DISABLED;
+        }
+        public boolean isMuted() {
+            return mute == MUTE_MUTED;
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 4eb0567..b4afb7d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -17,6 +17,7 @@
 package com.android.settingslib.bluetooth;
 
 import static com.android.settingslib.flags.Flags.enableSetPreferredTransportForLeAudioDevice;
+import static com.android.settingslib.flags.Flags.ignoreA2dpDisconnectionForAndroidAuto;
 
 import android.annotation.CallbackExecutor;
 import android.annotation.StringRes;
@@ -82,6 +83,8 @@
  */
 public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> {
     private static final String TAG = "CachedBluetoothDevice";
+    private static final ParcelUuid ANDROID_AUTO_UUID =
+            ParcelUuid.fromString("4de17a00-52cb-11e6-bdf4-0800200c9a66");
 
     // See mConnectAttempted
     private static final long MAX_UUID_DELAY_FOR_AUTO_CONNECT = 5000;
@@ -260,18 +263,26 @@
                         if (mHandler.hasMessages(profile.getProfileId())) {
                             mHandler.removeMessages(profile.getProfileId());
                             if (profile.getConnectionPolicy(mDevice) >
-                                BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
-                                /*
-                                 * If we received state DISCONNECTED and previous state was
-                                 * CONNECTING and connection policy is FORBIDDEN or UNKNOWN
-                                 * then it's not really a failure to connect.
-                                 *
-                                 * Connection profile is considered as failed when connection
-                                 * policy indicates that profile should be connected
-                                 * but it got disconnected.
-                                 */
-                                Log.w(TAG, "onProfileStateChanged(): Failed to connect profile");
-                                setProfileConnectedStatus(profile.getProfileId(), true);
+                                    BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
+                                if (ignoreA2dpDisconnectionForAndroidAuto()
+                                        && profile instanceof A2dpProfile && isAndroidAuto()) {
+                                    Log.w(TAG,
+                                            "onProfileStateChanged(): Skip setting A2DP "
+                                                    + "connection fail for Android Auto");
+                                } else {
+                                    /*
+                                     * If we received state DISCONNECTED and previous state was
+                                     * CONNECTING and connection policy is FORBIDDEN or UNKNOWN
+                                     * then it's not really a failure to connect.
+                                     *
+                                     * Connection profile is considered as failed when connection
+                                     * policy indicates that profile should be connected
+                                     * but it got disconnected.
+                                     */
+                                    Log.w(TAG,
+                                            "onProfileStateChanged(): Failed to connect profile");
+                                    setProfileConnectedStatus(profile.getProfileId(), true);
+                                }
                             }
                         }
                         break;
@@ -1580,6 +1591,12 @@
 
     private int getHearingDeviceSummaryRes(int leftBattery, int rightBattery,
             boolean shortSummary) {
+        if (getDeviceSide() == HearingAidInfo.DeviceSide.SIDE_MONO
+                || getDeviceSide() == HearingAidInfo.DeviceSide.SIDE_LEFT_AND_RIGHT) {
+            return !shortSummary && (getBatteryLevel() > BluetoothDevice.BATTERY_LEVEL_UNKNOWN)
+                    ? R.string.bluetooth_active_battery_level
+                    : R.string.bluetooth_active_no_battery_level;
+        }
         boolean isLeftDeviceConnected = getConnectedHearingAidSide(
                 HearingAidInfo.DeviceSide.SIDE_LEFT).isPresent();
         boolean isRightDeviceConnected = getConnectedHearingAidSide(
@@ -1635,8 +1652,7 @@
             @HearingAidInfo.DeviceSide int side) {
         return Stream.concat(Stream.of(this, mSubDevice), mMemberDevices.stream())
                 .filter(Objects::nonNull)
-                .filter(device -> device.getDeviceSide() == side
-                        || device.getDeviceSide() == HearingAidInfo.DeviceSide.SIDE_LEFT_AND_RIGHT)
+                .filter(device -> device.getDeviceSide() == side)
                 .filter(device -> device.getDevice().isConnected())
                 // For hearing aids, we should expect only one device assign to one side, but if
                 // it happens, we don't care which one.
@@ -1900,6 +1916,25 @@
                 BluetoothProfile.STATE_CONNECTED;
     }
 
+    /**
+     * @return {@code true} if {@code cachedBluetoothDevice} supports broadcast assistant profile
+     */
+    public boolean isConnectedLeAudioBroadcastAssistantDevice() {
+        LocalBluetoothLeBroadcastAssistant leBroadcastAssistant =
+                mProfileManager.getLeAudioBroadcastAssistantProfile();
+        return leBroadcastAssistant != null && leBroadcastAssistant.getConnectionStatus(mDevice)
+                == BluetoothProfile.STATE_CONNECTED;
+    }
+
+    /**
+     * @return {@code true} if {@code cachedBluetoothDevice} supports volume control profile
+     */
+    public boolean isConnectedVolumeControlDevice() {
+        VolumeControlProfile volumeControl = mProfileManager.getVolumeControlProfile();
+        return volumeControl != null && volumeControl.getConnectionStatus(mDevice)
+                == BluetoothProfile.STATE_CONNECTED;
+    }
+
     private boolean isConnectedSapDevice() {
         SapProfile sapProfile = mProfileManager.getSapProfile();
         return sapProfile != null && sapProfile.getConnectionStatus(mDevice)
@@ -2031,4 +2066,16 @@
     void setLocalBluetoothManager(LocalBluetoothManager bluetoothManager) {
         mBluetoothManager = bluetoothManager;
     }
+
+    private boolean isAndroidAuto() {
+        try {
+            ParcelUuid[] uuids = mDevice.getUuids();
+            if (ArrayUtils.contains(uuids, ANDROID_AUTO_UUID)) {
+                return true;
+            }
+        } catch (RuntimeException e) {
+            Log.w(TAG, "Fail to check isAndroidAuto for " + this);
+        }
+        return false;
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index 7fdb32c..b754706 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -153,7 +153,7 @@
     /**
      * Returns device summary of the pair of the hearing aid / CSIP passed as the parameter.
      *
-     * @param CachedBluetoothDevice device
+     * @param device the remote device
      * @return Device summary, or if the pair does not exist or if it is not a hearing aid or
      * a CSIP set member, then {@code null}.
      */
@@ -394,6 +394,7 @@
     }
 
     public synchronized void onDeviceUnpaired(CachedBluetoothDevice device) {
+        mHearingAidDeviceManager.clearLocalDataIfNeeded(device);
         device.setGroupId(BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
         CachedBluetoothDevice mainDevice = mCsipDeviceManager.findMainDevice(device);
         // Should iterate through the cloned set to avoid ConcurrentModificationException
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
index fa28cf6..1ca4c2b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
@@ -18,7 +18,6 @@
 import android.bluetooth.BluetoothCsipSetCoordinator;
 import android.bluetooth.BluetoothHapClient;
 import android.bluetooth.BluetoothHearingAid;
-import android.bluetooth.BluetoothLeAudio;
 import android.bluetooth.BluetoothProfile;
 import android.bluetooth.BluetoothUuid;
 import android.bluetooth.le.ScanFilter;
@@ -308,6 +307,10 @@
         }
     }
 
+    void clearLocalDataIfNeeded(CachedBluetoothDevice device) {
+        HearingDeviceLocalDataManager.clear(mContext, device.getDevice());
+    }
+
     private void setAudioRoutingConfig(CachedBluetoothDevice device) {
         AudioDeviceAttributes hearingDeviceAttributes =
                 mRoutingHelper.getMatchedHearingDeviceAttributes(device);
@@ -428,8 +431,7 @@
                 p -> p instanceof HapClientProfile)) {
             int audioLocation = leAudioProfile.getAudioLocation(cachedDevice.getDevice());
             int hearingAidType = hapClientProfile.getHearingAidType(cachedDevice.getDevice());
-            if (audioLocation != BluetoothLeAudio.AUDIO_LOCATION_INVALID
-                    && hearingAidType != HapClientProfile.HearingAidType.TYPE_INVALID) {
+            if (hearingAidType != HapClientProfile.HearingAidType.TYPE_INVALID) {
                 final HearingAidInfo info = new HearingAidInfo.Builder()
                         .setLeAudioLocation(audioLocation)
                         .setHapDeviceType(hearingAidType)
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidInfo.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidInfo.java
index ef08c92..8399824 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidInfo.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidInfo.java
@@ -34,6 +34,7 @@
             DeviceSide.SIDE_LEFT,
             DeviceSide.SIDE_RIGHT,
             DeviceSide.SIDE_LEFT_AND_RIGHT,
+            DeviceSide.SIDE_MONO
     })
 
     /** Side definition for hearing aids. */
@@ -42,6 +43,7 @@
         int SIDE_LEFT = 0;
         int SIDE_RIGHT = 1;
         int SIDE_LEFT_AND_RIGHT = 2;
+        int SIDE_MONO = 3;
     }
 
     @Retention(java.lang.annotation.RetentionPolicy.SOURCE)
@@ -124,6 +126,9 @@
 
     @DeviceSide
     private static int convertLeAudioLocationToInternalSide(int leAudioLocation) {
+        if (leAudioLocation == BluetoothLeAudio.AUDIO_LOCATION_MONO) {
+            return DeviceSide.SIDE_MONO;
+        }
         boolean isLeft = (leAudioLocation & LE_AUDIO_LOCATION_LEFT) != 0;
         boolean isRight = (leAudioLocation & LE_AUDIO_LOCATION_RIGHT) != 0;
         if (isLeft && isRight) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingDeviceLocalDataManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingDeviceLocalDataManager.java
index 7a64965..6725558 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingDeviceLocalDataManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingDeviceLocalDataManager.java
@@ -86,6 +86,17 @@
         mSettingsObserver = new SettingsObserver(ThreadUtils.getUiThreadHandler());
     }
 
+    /**
+     * Clears the local data of the device. This method should be called when the device is
+     * unpaired.
+     */
+    public static void clear(@NonNull Context context, @NonNull BluetoothDevice device) {
+        HearingDeviceLocalDataManager manager = new HearingDeviceLocalDataManager(context);
+        manager.getLocalDataFromSettings();
+        manager.remove(device);
+        manager.putAmbientVolumeSettings();
+    }
+
     /** Starts the manager. Loads the data from Settings and start observing any changes. */
     public synchronized void start() {
         if (mIsStarted) {
@@ -141,6 +152,7 @@
      * Puts the local data of the corresponding hearing device.
      *
      * @param device the device to update the local data
+     * @param data the local data to be stored
      */
     private void put(BluetoothDevice device, Data data) {
         if (device == null) {
@@ -148,7 +160,11 @@
         }
         synchronized (sLock) {
             final String addr = device.getAnonymizedAddress();
-            mAddrToDataMap.put(addr, data);
+            if (data == null) {
+                mAddrToDataMap.remove(addr);
+            } else {
+                mAddrToDataMap.put(addr, data);
+            }
             if (mListener != null && mListenerExecutor != null) {
                 mListenerExecutor.execute(() -> mListener.onDeviceLocalDataChange(addr, data));
             }
@@ -156,6 +172,24 @@
     }
 
     /**
+     * Removes the local data of the corresponding hearing device.
+     *
+     * @param device the device to remove the local data
+     */
+    private void remove(BluetoothDevice device) {
+        if (device == null) {
+            return;
+        }
+        synchronized (sLock) {
+            final String addr = device.getAnonymizedAddress();
+            mAddrToDataMap.remove(addr);
+            if (mListener != null && mListenerExecutor != null) {
+                mListenerExecutor.execute(() -> mListener.onDeviceLocalDataChange(addr, null));
+            }
+        }
+    }
+
+    /**
      * Updates the ambient volume of the corresponding hearing device. This should be called after
      * {@link #start()} is called().
      *
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
index a4c5a00d..5bcdcc0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
@@ -32,7 +32,9 @@
 import android.os.Build;
 import android.util.Log;
 
+import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 
 import com.android.settingslib.R;
@@ -372,6 +374,27 @@
     }
 
     /**
+     * Gets the {@link BluetoothLeBroadcastMetadata} of a specified source added to this sink.
+     *
+     * @param sink Broadcast Sink device
+     * @param sourceId Broadcast source id
+     * @return metadata {@link BluetoothLeBroadcastMetadata} associated with the specified source.
+     */
+    public @Nullable BluetoothLeBroadcastMetadata getSourceMetadata(
+            @NonNull BluetoothDevice sink, @IntRange(from = 0x00, to = 0xFF) int sourceId) {
+        if (mService == null) {
+            Log.d(TAG, "The BluetoothLeBroadcastAssistant is null");
+            return null;
+        }
+        try {
+            return mService.getSourceMetadata(sink, sourceId);
+        } catch (IllegalArgumentException | NoSuchMethodError e) {
+            Log.w(TAG, "Error calling getSourceMetadata()", e);
+        }
+        return null;
+    }
+
+    /**
      * Register Broadcast Assistant Callbacks to track its state and receivers
      *
      * @param executor Executor object for callback
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java
index 76aa5bf..478a5d1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java
@@ -80,8 +80,14 @@
                     // behavior.
                     @AudioDeviceType int deviceTypeToActivate = mSelectedInputDeviceType;
                     for (AudioDeviceInfo info : addedDevices) {
-                        if (InputMediaDevice.isSupportedInputDevice(info.getType())) {
-                            deviceTypeToActivate = info.getType();
+                        @AudioDeviceType int type = info.getType();
+                        // Since onAudioDevicesAdded is called not only when new device is hot
+                        // plugged, but also when the switcher dialog is opened, make sure to check
+                        // against existing device list and only activate if the device does not
+                        // exist previously.
+                        if (InputMediaDevice.isSupportedInputDevice(type)
+                                && findDeviceByType(type) == null) {
+                            deviceTypeToActivate = type;
                         }
                     }
 
@@ -140,16 +146,22 @@
     }
 
     // TODO(b/355684672): handle edge case where there are two devices with the same type. Only
-    // using a single mSelectedInputDeviceType might not be enough to recognize the correct device.
-    public @Nullable MediaDevice getSelectedInputDevice() {
+    // using a single type might not be enough to recognize the correct device.
+    @Nullable
+    private MediaDevice findDeviceByType(@AudioDeviceType int type) {
         for (MediaDevice device : mInputMediaDevices) {
-            if (((InputMediaDevice) device).getAudioDeviceInfoType() == mSelectedInputDeviceType) {
+            if (((InputMediaDevice) device).getAudioDeviceInfoType() == type) {
                 return device;
             }
         }
         return null;
     }
 
+    @Nullable
+    public MediaDevice getSelectedInputDevice() {
+        return findDeviceByType(mSelectedInputDeviceType);
+    }
+
     private void applyDefaultSelectedTypeToAllPresets() {
         mSelectedInputDeviceType = retrieveDefaultSelectedDeviceType();
         AudioDeviceAttributes deviceAttributes =
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
index a7e0464..e01f279 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
@@ -27,6 +27,7 @@
 import android.net.wifi.sharedconnectivity.app.NetworkProviderInfo
 import android.os.Bundle
 import android.os.SystemClock
+import android.security.advancedprotection.AdvancedProtectionManager
 import android.util.Log
 import android.view.WindowManager
 import androidx.annotation.VisibleForTesting
@@ -498,7 +499,13 @@
         ): Job =
             coroutineScope.launch {
                 val wifiManager = context.getSystemService(WifiManager::class.java) ?: return@launch
-                if (wifiManager.isWepSupported == true && wifiManager.queryWepAllowed()) {
+                val aapmManager = context.getSystemService(AdvancedProtectionManager::class.java)
+                if (isAdvancedProtectionEnabled(aapmManager)) {
+                    val intent = aapmManager.createSupportIntent(
+                        AdvancedProtectionManager.FEATURE_ID_DISALLOW_WEP,
+                        AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION)
+                    onStartActivity(intent)
+                } else if (wifiManager.isWepSupported == true && wifiManager.queryWepAllowed()) {
                     onAllowed()
                 } else {
                     val intent = Intent(Intent.ACTION_MAIN).apply {
@@ -522,6 +529,18 @@
                 }
             }
 
+        private suspend fun isAdvancedProtectionEnabled(
+            aapmManager: AdvancedProtectionManager?
+        ): Boolean =
+            if (android.security.Flags.aapmApi() &&
+                    com.android.wifi.flags.Flags.wepDisabledInApm() &&
+                    aapmManager != null
+            ) {
+                withContext(Dispatchers.Default) { aapmManager.isAdvancedProtectionEnabled() }
+            } else {
+                false
+            }
+
         const val SSID = "ssid"
         const val DIALOG_WINDOW_TYPE = "dialog_window_type"
     }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
index a03977c1..785bcbf 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
@@ -21,15 +21,26 @@
 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT;
 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
+import static android.security.advancedprotection.AdvancedProtectionManager.ADVANCED_PROTECTION_SYSTEM_ENTITY;
+
 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
 import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.admin.Authority;
+import android.app.admin.DeviceAdminAuthority;
 import android.app.admin.DevicePolicyManager;
+import android.app.admin.DpcAuthority;
+import android.app.admin.EnforcingAdmin;
+import android.app.admin.RoleAuthority;
+import android.app.admin.UnknownAuthority;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -37,8 +48,13 @@
 import android.content.pm.UserInfo;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
@@ -52,6 +68,8 @@
 
 @RunWith(RobolectricTestRunner.class)
 public class RestrictedLockUtilsTest {
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
 
     @Mock
     private Context mContext;
@@ -66,6 +84,7 @@
 
     private final int mUserId = 194;
     private final int mProfileId = 160;
+    private final String mPackage = "test.pkg";
     private final ComponentName mAdmin1 = new ComponentName("admin1", "admin1class");
     private final ComponentName mAdmin2 = new ComponentName("admin2", "admin2class");
 
@@ -85,6 +104,7 @@
         RestrictedLockUtilsInternal.sProxy = mProxy;
     }
 
+    @RequiresFlagsDisabled(android.security.Flags.FLAG_AAPM_API)
     @Test
     public void checkIfRestrictionEnforced_deviceOwner()
             throws PackageManager.NameNotFoundException {
@@ -109,6 +129,7 @@
         assertThat(enforcedAdmin.component).isEqualTo(mAdmin1);
     }
 
+    @RequiresFlagsDisabled(android.security.Flags.FLAG_AAPM_API)
     @Test
     public void checkIfRestrictionEnforced_profileOwner()
             throws PackageManager.NameNotFoundException {
@@ -133,6 +154,125 @@
         assertThat(enforcedAdmin.component).isEqualTo(mAdmin1);
     }
 
+    @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+    @Test
+    public void checkIfRestrictionEnforced_getEnforcingAdminExists() {
+        UserManager.EnforcingUser enforcingUser = new UserManager.EnforcingUser(mUserId,
+                UserManager.RESTRICTION_SOURCE_PROFILE_OWNER);
+        final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+        final EnforcingAdmin enforcingAdmin = new EnforcingAdmin(mPackage,
+                UnknownAuthority.UNKNOWN_AUTHORITY, UserHandle.of(mUserId), mAdmin1);
+
+        when(mUserManager.getUserRestrictionSources(userRestriction,
+                UserHandle.of(mUserId)))
+                .thenReturn(Collections.singletonList(enforcingUser));
+        when(mDevicePolicyManager.getEnforcingAdmin(mUserId, userRestriction))
+                .thenReturn(enforcingAdmin);
+
+        EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
+                mContext, userRestriction, mUserId);
+
+        assertThat(enforcedAdmin).isNotNull();
+        assertThat(enforcedAdmin.enforcedRestriction).isEqualTo(userRestriction);
+        assertThat(enforcedAdmin.component).isEqualTo(enforcingAdmin.getComponentName());
+        assertThat(enforcedAdmin.user).isEqualTo(enforcingAdmin.getUserHandle());
+    }
+
+    @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+    @Test
+    public void checkIfRestrictionEnforced_getEnforcingAdminReturnsNull_deviceOwner()
+            throws PackageManager.NameNotFoundException {
+        UserManager.EnforcingUser enforcingUser = new UserManager.EnforcingUser(mUserId,
+                UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
+        final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+
+        when(mUserManager.getUserRestrictionSources(userRestriction,
+                UserHandle.of(mUserId)))
+                .thenReturn(Collections.singletonList(enforcingUser));
+        when(mDevicePolicyManager.getEnforcingAdmin(mUserId, userRestriction))
+                .thenReturn(null);
+        when(mContext.createPackageContextAsUser(any(), eq(0),
+                eq(UserHandle.of(mUserId))))
+                .thenReturn(mContext);
+
+        setUpDeviceOwner(mAdmin1, mUserId);
+
+        EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal
+                .checkIfRestrictionEnforced(mContext, userRestriction, mUserId);
+
+        assertThat(enforcedAdmin).isNotNull();
+        assertThat(enforcedAdmin.enforcedRestriction).isEqualTo(userRestriction);
+        assertThat(enforcedAdmin.component).isEqualTo(mAdmin1);
+    }
+
+    @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+    @Test
+    public void checkIfRestrictionEnforced_getEnforcingAdminReturnsNull_profileOwner()
+            throws PackageManager.NameNotFoundException {
+        UserManager.EnforcingUser enforcingUser = new UserManager.EnforcingUser(mUserId,
+                UserManager.RESTRICTION_SOURCE_PROFILE_OWNER);
+        final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+
+        when(mUserManager.getUserRestrictionSources(userRestriction,
+                UserHandle.of(mUserId)))
+                .thenReturn(Collections.singletonList(enforcingUser));
+        when(mDevicePolicyManager.getEnforcingAdmin(mUserId, userRestriction))
+                .thenReturn(null);
+        when(mContext.createPackageContextAsUser(any(), eq(0),
+                eq(UserHandle.of(mUserId))))
+                .thenReturn(mContext);
+
+        setUpProfileOwner(mAdmin1);
+
+        EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal
+                .checkIfRestrictionEnforced(mContext, userRestriction, mUserId);
+
+        assertThat(enforcedAdmin).isNotNull();
+        assertThat(enforcedAdmin.enforcedRestriction).isEqualTo(userRestriction);
+        assertThat(enforcedAdmin.component).isEqualTo(mAdmin1);
+    }
+
+    @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+    @Test
+    public void isPolicyEnforcedByAdvancedProtection_notEnforced_returnsFalse() {
+        final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+        final Authority[] allNonAdvancedProtectionAuthorities = new Authority[] {
+                UnknownAuthority.UNKNOWN_AUTHORITY,
+                DeviceAdminAuthority.DEVICE_ADMIN_AUTHORITY,
+                DpcAuthority.DPC_AUTHORITY,
+                new RoleAuthority(Collections.singleton("some-role"))
+        };
+
+        for (Authority authority : allNonAdvancedProtectionAuthorities) {
+            final EnforcingAdmin enforcingAdmin = new EnforcingAdmin(mPackage, authority,
+                    UserHandle.of(mUserId), mAdmin1);
+
+            when(mDevicePolicyManager.getEnforcingAdmin(mUserId, userRestriction))
+                    .thenReturn(enforcingAdmin);
+
+            assertWithMessage(authority + " is not an advanced protection authority")
+                    .that(RestrictedLockUtilsInternal.isPolicyEnforcedByAdvancedProtection(
+                            mContext, userRestriction, mUserId))
+                    .isFalse();
+        }
+    }
+
+    @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+    @Test
+    public void isPolicyEnforcedByAdvancedProtection_enforced_returnsTrue() {
+        final Authority advancedProtectionAuthority = new UnknownAuthority(
+                ADVANCED_PROTECTION_SYSTEM_ENTITY);
+        final EnforcingAdmin advancedProtectionEnforcingAdmin = new EnforcingAdmin(mPackage,
+                advancedProtectionAuthority, UserHandle.of(mUserId), mAdmin1);
+        final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+
+        when(mDevicePolicyManager.getEnforcingAdmin(mUserId, userRestriction))
+                .thenReturn(advancedProtectionEnforcingAdmin);
+
+        assertThat(RestrictedLockUtilsInternal.isPolicyEnforcedByAdvancedProtection(mContext,
+                userRestriction, mUserId)).isTrue();
+    }
+
     @Test
     public void checkIfDevicePolicyServiceDisabled_noEnforceAdminForManagedProfile() {
         when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(null);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedPreferenceHelperTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedPreferenceHelperTest.java
index 7ad54e1..dbbbd5b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedPreferenceHelperTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedPreferenceHelperTest.java
@@ -16,7 +16,10 @@
 
 package com.android.settingslib;
 
+import static android.security.advancedprotection.AdvancedProtectionManager.ADVANCED_PROTECTION_SYSTEM_ENTITY;
+
 import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
@@ -26,10 +29,23 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.admin.Authority;
+import android.app.admin.DeviceAdminAuthority;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyResourcesManager;
+import android.app.admin.DpcAuthority;
+import android.app.admin.EnforcingAdmin;
+import android.app.admin.RoleAuthority;
+import android.app.admin.UnknownAuthority;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.view.View;
 import android.widget.TextView;
 
@@ -37,14 +53,19 @@
 import androidx.preference.PreferenceViewHolder;
 
 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 org.robolectric.RobolectricTestRunner;
 
+import java.util.Collections;
+
 @RunWith(RobolectricTestRunner.class)
 public class RestrictedPreferenceHelperTest {
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
 
     @Mock
     private Context mContext;
@@ -57,6 +78,11 @@
     @Mock
     private RestrictedTopLevelPreference mRestrictedTopLevelPreference;
 
+    private final String mPackage = "test.pkg";
+    private final ComponentName mAdmin = new ComponentName("admin", "adminclass");
+    private final Authority mAdvancedProtectionAuthority = new UnknownAuthority(
+            ADVANCED_PROTECTION_SYSTEM_ENTITY);
+
     private PreferenceViewHolder mViewHolder;
     private RestrictedPreferenceHelper mHelper;
 
@@ -71,6 +97,7 @@
         mHelper = new RestrictedPreferenceHelper(mContext, mPreference, null);
     }
 
+    @RequiresFlagsDisabled(android.security.Flags.FLAG_AAPM_API)
     @Test
     public void bindPreference_disabled_shouldDisplayDisabledSummary() {
         final TextView summaryView = mock(TextView.class, RETURNS_DEEP_STUBS);
@@ -101,6 +128,57 @@
         verify(summaryView, never()).setVisibility(View.GONE);
     }
 
+    @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+    @Test
+    public void bindPreference_disabled_byAdvancedProtection_shouldDisplayDisabledSummary() {
+        final TextView summaryView = mock(TextView.class, RETURNS_DEEP_STUBS);
+        final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+        final RestrictedLockUtils.EnforcedAdmin enforcedAdmin = new RestrictedLockUtils
+                .EnforcedAdmin(/* component */ null, userRestriction, UserHandle.of(
+                        UserHandle.myUserId()));
+        final EnforcingAdmin advancedProtectionEnforcingAdmin = new EnforcingAdmin(mPackage,
+                mAdvancedProtectionAuthority, UserHandle.of(UserHandle.myUserId()), mAdmin);
+
+        when(mViewHolder.itemView.findViewById(android.R.id.summary))
+                .thenReturn(summaryView);
+        when(mDevicePolicyManager.getEnforcingAdmin(UserHandle.myUserId(), userRestriction))
+                .thenReturn(advancedProtectionEnforcingAdmin);
+        when(mContext.getString(
+                com.android.settingslib.widget.restricted.R.string.disabled_by_advanced_protection))
+                .thenReturn("advanced_protection");
+
+        mHelper.useAdminDisabledSummary(true);
+        mHelper.setDisabledByAdmin(enforcedAdmin);
+        mHelper.onBindViewHolder(mViewHolder);
+
+        verify(summaryView).setText("advanced_protection");
+        verify(summaryView, never()).setVisibility(View.GONE);
+    }
+
+    @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+    @Test
+    public void bindPreference_disabled_byAdmin_shouldDisplayDisabledSummary() {
+        final TextView summaryView = mock(TextView.class, RETURNS_DEEP_STUBS);
+        final EnforcingAdmin nonAdvancedProtectionEnforcingAdmin = new EnforcingAdmin(mPackage,
+                UnknownAuthority.UNKNOWN_AUTHORITY, UserHandle.of(UserHandle.myUserId()), mAdmin);
+        final String userRestriction = UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY;
+
+        when(mViewHolder.itemView.findViewById(android.R.id.summary))
+                .thenReturn(summaryView);
+        when(mDevicePolicyManager.getEnforcingAdmin(UserHandle.myUserId(), userRestriction))
+                .thenReturn(nonAdvancedProtectionEnforcingAdmin);
+        when(mContext.getString(R.string.disabled_by_admin_summary_text))
+                .thenReturn("test");
+        when(mDevicePolicyResourcesManager.getString(any(), any())).thenReturn("test");
+
+        mHelper.useAdminDisabledSummary(true);
+        mHelper.setDisabledByAdmin(new RestrictedLockUtils.EnforcedAdmin());
+        mHelper.onBindViewHolder(mViewHolder);
+
+        verify(summaryView).setText("test");
+        verify(summaryView, never()).setVisibility(View.GONE);
+    }
+
     @Test
     public void bindPreference_notDisabled_shouldNotHideSummary() {
         final TextView summaryView = mock(TextView.class, RETURNS_DEEP_STUBS);
@@ -157,4 +235,74 @@
 
         assertThat(mHelper.isDisabledByAdmin()).isTrue();
     }
+
+    @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+    @Test
+    public void setDisabledByAdmin_previousAndCurrentAdminsAreTheSame_returnsFalse() {
+        RestrictedLockUtils.EnforcedAdmin enforcedAdmin =
+                new RestrictedLockUtils.EnforcedAdmin(/* component */ null,
+                        /* enforcedRestriction */ "some_restriction", /* userHandle */ null);
+
+        mHelper.setDisabledByAdmin(enforcedAdmin);
+
+        assertThat(mHelper.setDisabledByAdmin(enforcedAdmin)).isFalse();
+    }
+
+    @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+    @Test
+    public void setDisabledByAdmin_previousAndCurrentAdminsAreDifferent_returnsTrue() {
+        RestrictedLockUtils.EnforcedAdmin enforcedAdmin1 =
+                new RestrictedLockUtils.EnforcedAdmin(/* component */ null,
+                        /* enforcedRestriction */ "some_restriction", /* userHandle */ null);
+        RestrictedLockUtils.EnforcedAdmin enforcedAdmin2 =
+                new RestrictedLockUtils.EnforcedAdmin(new ComponentName("pkg", "cls"),
+                        /* enforcedRestriction */ "some_restriction", /* userHandle */ null);
+
+        mHelper.setDisabledByAdmin(enforcedAdmin1);
+
+        assertThat(mHelper.setDisabledByAdmin(enforcedAdmin2)).isTrue();
+    }
+
+    @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+    @Test
+    public void isRestrictionEnforcedByAdvancedProtection_notEnforced_returnsFalse() {
+        final Authority[] allNonAdvancedProtectionAuthorities = new Authority[] {
+                UnknownAuthority.UNKNOWN_AUTHORITY,
+                DeviceAdminAuthority.DEVICE_ADMIN_AUTHORITY,
+                DpcAuthority.DPC_AUTHORITY,
+                new RoleAuthority(Collections.singleton("some-role"))
+        };
+        final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+
+        for (Authority authority : allNonAdvancedProtectionAuthorities) {
+            final EnforcingAdmin enforcingAdmin = new EnforcingAdmin(mPackage, authority,
+                    UserHandle.of(UserHandle.myUserId()), mAdmin);
+
+            when(mDevicePolicyManager.getEnforcingAdmin(UserHandle.myUserId(), userRestriction))
+                    .thenReturn(enforcingAdmin);
+
+            mHelper.setDisabledByAdmin(new RestrictedLockUtils.EnforcedAdmin(/* component */ null,
+                    userRestriction, UserHandle.of(UserHandle.myUserId())));
+
+            assertWithMessage(authority + " is not an advanced protection authority")
+                    .that(mHelper.isRestrictionEnforcedByAdvancedProtection())
+                    .isFalse();
+        }
+    }
+
+    @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+    @Test
+    public void isRestrictionEnforcedByAdvancedProtection_enforced_returnsTrue() {
+        final EnforcingAdmin advancedProtectionEnforcingAdmin = new EnforcingAdmin(mPackage,
+                mAdvancedProtectionAuthority, UserHandle.of(UserHandle.myUserId()), mAdmin);
+        final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+
+        when(mDevicePolicyManager.getEnforcingAdmin(UserHandle.myUserId(), userRestriction))
+                .thenReturn(advancedProtectionEnforcingAdmin);
+
+        mHelper.setDisabledByAdmin(new RestrictedLockUtils.EnforcedAdmin(/* component */ null,
+                userRestriction, UserHandle.of(UserHandle.myUserId())));
+
+        assertThat(mHelper.isRestrictionEnforcedByAdvancedProtection()).isTrue();
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/AmbientVolumeControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/AmbientVolumeControllerTest.java
new file mode 100644
index 0000000..abc1d226
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/AmbientVolumeControllerTest.java
@@ -0,0 +1,318 @@
+/*
+ * 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.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.AudioInputControl;
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+
+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 org.robolectric.RobolectricTestRunner;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/** Tests for {@link AmbientVolumeController}. */
+@RunWith(RobolectricTestRunner.class)
+public class AmbientVolumeControllerTest {
+
+    @Rule
+    public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    private static final String TEST_ADDRESS = "00:00:00:00:11";
+
+    @Mock
+    private LocalBluetoothProfileManager mProfileManager;
+    @Mock
+    private VolumeControlProfile mVolumeControlProfile;
+    @Mock
+    private AmbientVolumeController.AmbientVolumeControlCallback mCallback;
+    @Mock
+    private BluetoothDevice mDevice;
+
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private AmbientVolumeController mVolumeController;
+
+    @Before
+    public void setUp() {
+        when(mProfileManager.getVolumeControlProfile()).thenReturn(mVolumeControlProfile);
+        when(mDevice.getAddress()).thenReturn(TEST_ADDRESS);
+        when(mDevice.isConnected()).thenReturn(true);
+        mVolumeController = new AmbientVolumeController(mProfileManager, mCallback);
+    }
+
+    @Test
+    public void onServiceConnected_notifyCallback() {
+        when(mVolumeControlProfile.isProfileReady()).thenReturn(true);
+
+        mVolumeController.onServiceConnected();
+
+        verify(mCallback).onVolumeControlServiceConnected();
+    }
+
+    @Test
+    public void isAmbientControlAvailable_validControls_assertTrue() {
+        prepareValidAmbientControls();
+
+        assertThat(mVolumeController.isAmbientControlAvailable(mDevice)).isTrue();
+    }
+
+    @Test
+    public void isAmbientControlAvailable_streamingControls_assertFalse() {
+        prepareStreamingControls();
+
+        assertThat(mVolumeController.isAmbientControlAvailable(mDevice)).isFalse();
+    }
+
+    @Test
+    public void isAmbientControlAvailable_automaticAmbientControls_assertFalse() {
+        prepareAutomaticAmbientControls();
+
+        assertThat(mVolumeController.isAmbientControlAvailable(mDevice)).isFalse();
+    }
+
+    @Test
+    public void isAmbientControlAvailable_inactiveAmbientControls_assertFalse() {
+        prepareInactiveAmbientControls();
+
+        assertThat(mVolumeController.isAmbientControlAvailable(mDevice)).isFalse();
+    }
+
+    @Test
+    public void registerCallback_verifyRegisterOnAllControls() {
+        List<AudioInputControl> controls = prepareValidAmbientControls();
+
+        mVolumeController.registerCallback(mContext.getMainExecutor(), mDevice);
+
+        for (AudioInputControl control : controls) {
+            verify(control).registerCallback(any(Executor.class), any());
+        }
+    }
+
+    @Test
+    public void unregisterCallback_verifyUnregisterOnAllControls() {
+        List<AudioInputControl> controls = prepareValidAmbientControls();
+
+        mVolumeController.registerCallback(mContext.getMainExecutor(), mDevice);
+        mVolumeController.unregisterCallback(mDevice);
+
+        for (AudioInputControl control : controls) {
+            verify(control).unregisterCallback(any());
+        }
+    }
+
+    @Test
+    public void getAmbientMax_verifyGetOnFirstControl() {
+        List<AudioInputControl> controls = prepareValidAmbientControls();
+
+        mVolumeController.getAmbientMax(mDevice);
+
+        verify(controls.getFirst()).getGainSettingMax();
+    }
+
+    @Test
+    public void getAmbientMin_verifyGetOnFirstControl() {
+        List<AudioInputControl> controls = prepareValidAmbientControls();
+
+        mVolumeController.getAmbientMin(mDevice);
+
+        verify(controls.getFirst()).getGainSettingMin();
+    }
+
+    @Test
+    public void getAmbient_verifyGetOnFirstControl() {
+        List<AudioInputControl> controls = prepareValidAmbientControls();
+
+        mVolumeController.getAmbient(mDevice);
+
+        verify(controls.getFirst()).getGainSetting();
+    }
+
+    @Test
+    public void setAmbient_verifySetOnAllControls() {
+        List<AudioInputControl> controls = prepareValidAmbientControls();
+
+        mVolumeController.setAmbient(mDevice, 10);
+
+        for (AudioInputControl control : controls) {
+            verify(control).setGainSetting(10);
+        }
+    }
+
+    @Test
+    public void getMute_verifyGetOnFirstControl() {
+        List<AudioInputControl> controls = prepareValidAmbientControls();
+
+        mVolumeController.getMute(mDevice);
+
+        verify(controls.getFirst()).getMute();
+    }
+
+    @Test
+    public void setMuted_true_verifySetOnAllControls() {
+        List<AudioInputControl> controls = prepareValidAmbientControls();
+
+        mVolumeController.setMuted(mDevice, true);
+
+        for (AudioInputControl control : controls) {
+            verify(control).setMute(AudioInputControl.MUTE_MUTED);
+        }
+    }
+
+    @Test
+    public void setMuted_false_verifySetOnAllControls() {
+        List<AudioInputControl> controls = prepareValidAmbientControls();
+
+        mVolumeController.setMuted(mDevice, false);
+
+        for (AudioInputControl control : controls) {
+            verify(control).setMute(AudioInputControl.MUTE_NOT_MUTED);
+        }
+    }
+
+    @Test
+    public void ambientCallback_onGainSettingChanged_verifyCallbackIsCalledWhenStateChange() {
+        AmbientVolumeController.AmbientCallback ambientCallback =
+                mVolumeController.new AmbientCallback(mDevice, mCallback);
+        final int testAmbient = 10;
+        List<AudioInputControl> controls = prepareValidAmbientControls();
+        when(controls.getFirst().getGainSetting()).thenReturn(testAmbient);
+
+        mVolumeController.refreshAmbientState(mDevice);
+        ambientCallback.onGainSettingChanged(testAmbient);
+        verify(mCallback, never()).onAmbientChanged(mDevice, testAmbient);
+
+        final int updatedTestAmbient = 20;
+        ambientCallback.onGainSettingChanged(updatedTestAmbient);
+        verify(mCallback).onAmbientChanged(mDevice, updatedTestAmbient);
+    }
+
+
+    @Test
+    public void ambientCallback_onSetAmbientFailed_verifyCallbackIsCalled() {
+        AmbientVolumeController.AmbientCallback ambientCallback =
+                mVolumeController.new AmbientCallback(mDevice, mCallback);
+
+        ambientCallback.onSetGainSettingFailed();
+
+        verify(mCallback).onCommandFailed(mDevice);
+    }
+
+    @Test
+    public void ambientCallback_onMuteChanged_verifyCallbackIsCalledWhenStateChange() {
+        AmbientVolumeController.AmbientCallback ambientCallback =
+                mVolumeController.new AmbientCallback(mDevice, mCallback);
+        final int testMute = 0;
+        List<AudioInputControl> controls = prepareValidAmbientControls();
+        when(controls.getFirst().getMute()).thenReturn(testMute);
+
+        mVolumeController.refreshAmbientState(mDevice);
+        ambientCallback.onMuteChanged(testMute);
+        verify(mCallback, never()).onMuteChanged(mDevice, testMute);
+
+        final int updatedTestMute = 1;
+        ambientCallback.onMuteChanged(updatedTestMute);
+        verify(mCallback).onMuteChanged(mDevice, updatedTestMute);
+    }
+
+    @Test
+    public void ambientCallback_onSetMuteFailed_verifyCallbackIsCalled() {
+        AmbientVolumeController.AmbientCallback ambientCallback =
+                mVolumeController.new AmbientCallback(mDevice, mCallback);
+
+        ambientCallback.onSetMuteFailed();
+
+        verify(mCallback).onCommandFailed(mDevice);
+    }
+
+    private List<AudioInputControl> prepareValidAmbientControls() {
+        List<AudioInputControl> controls = new ArrayList<>();
+        final int controlsCount = 2;
+        for (int i = 0; i < controlsCount; i++) {
+            controls.add(prepareAudioInputControl(
+                    AudioInputControl.AUDIO_INPUT_TYPE_AMBIENT,
+                    AudioInputControl.GAIN_MODE_MANUAL,
+                    AudioInputControl.AUDIO_INPUT_STATUS_ACTIVE));
+        }
+        when(mVolumeControlProfile.getAudioInputControlServices(mDevice)).thenReturn(controls);
+        return controls;
+    }
+
+    private List<AudioInputControl> prepareStreamingControls() {
+        List<AudioInputControl> controls = new ArrayList<>();
+        final int controlsCount = 2;
+        for (int i = 0; i < controlsCount; i++) {
+            controls.add(prepareAudioInputControl(
+                    AudioInputControl.AUDIO_INPUT_TYPE_STREAMING,
+                    AudioInputControl.GAIN_MODE_MANUAL,
+                    AudioInputControl.AUDIO_INPUT_STATUS_ACTIVE));
+        }
+        when(mVolumeControlProfile.getAudioInputControlServices(mDevice)).thenReturn(controls);
+        return controls;
+    }
+
+    private List<AudioInputControl> prepareAutomaticAmbientControls() {
+        List<AudioInputControl> controls = new ArrayList<>();
+        final int controlsCount = 2;
+        for (int i = 0; i < controlsCount; i++) {
+            controls.add(prepareAudioInputControl(
+                    AudioInputControl.AUDIO_INPUT_TYPE_STREAMING,
+                    AudioInputControl.GAIN_MODE_AUTOMATIC,
+                    AudioInputControl.AUDIO_INPUT_STATUS_ACTIVE));
+        }
+        when(mVolumeControlProfile.getAudioInputControlServices(mDevice)).thenReturn(controls);
+        return controls;
+    }
+
+    private List<AudioInputControl> prepareInactiveAmbientControls() {
+        List<AudioInputControl> controls = new ArrayList<>();
+        final int controlsCount = 2;
+        for (int i = 0; i < controlsCount; i++) {
+            controls.add(prepareAudioInputControl(
+                    AudioInputControl.AUDIO_INPUT_TYPE_STREAMING,
+                    AudioInputControl.GAIN_MODE_AUTOMATIC,
+                    AudioInputControl.AUDIO_INPUT_STATUS_INACTIVE));
+        }
+        when(mVolumeControlProfile.getAudioInputControlServices(mDevice)).thenReturn(controls);
+        return controls;
+    }
+
+    private AudioInputControl prepareAudioInputControl(int type, int mode, int status) {
+        AudioInputControl control = mock(AudioInputControl.class);
+        when(control.getAudioInputType()).thenReturn(type);
+        when(control.getGainMode()).thenReturn(mode);
+        when(control.getAudioInputStatus()).thenReturn(status);
+        return control;
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
index 8cc9974..05f471f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
@@ -139,6 +139,11 @@
         mCachedDevice1 = spy(new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice1));
         mCachedDevice2 = spy(new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice2));
         mCachedDevice3 = spy(new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice3));
+
+        mHearingAidDeviceManager = spy(new HearingAidDeviceManager(mContext, mLocalBluetoothManager,
+                mCachedDeviceManager.mCachedDevices));
+        mCachedDeviceManager.mHearingAidDeviceManager = mHearingAidDeviceManager;
+        doNothing().when(mHearingAidDeviceManager).clearLocalDataIfNeeded(any());
     }
 
     /**
@@ -338,6 +343,8 @@
 
         // Call onDeviceUnpaired for the one in mCachedDevices.
         mCachedDeviceManager.onDeviceUnpaired(cachedDevice2);
+
+        verify(mHearingAidDeviceManager).clearLocalDataIfNeeded(cachedDevice2);
         verify(mDevice1).removeBond();
     }
 
@@ -353,6 +360,8 @@
 
         // Call onDeviceUnpaired for the one in mCachedDevices.
         mCachedDeviceManager.onDeviceUnpaired(cachedDevice1);
+
+        verify(mHearingAidDeviceManager).clearLocalDataIfNeeded(cachedDevice1);
         verify(mDevice2).removeBond();
     }
 
@@ -406,9 +415,6 @@
      */
     @Test
     public void updateHearingAidDevices_directToHearingAidDeviceManager() {
-        mHearingAidDeviceManager = spy(new HearingAidDeviceManager(mContext, mLocalBluetoothManager,
-                mCachedDeviceManager.mCachedDevices));
-        mCachedDeviceManager.mHearingAidDeviceManager = mHearingAidDeviceManager;
         mCachedDeviceManager.updateHearingAidsDevices();
 
         verify(mHearingAidDeviceManager).updateHearingAidsDevices();
@@ -535,6 +541,7 @@
         // Call onDeviceUnpaired for the one in mCachedDevices.
         mCachedDeviceManager.onDeviceUnpaired(cachedDevice1);
 
+        verify(mHearingAidDeviceManager).clearLocalDataIfNeeded(cachedDevice1);
         verify(mDevice2).removeBond();
         assertThat(cachedDevice1.getGroupId()).isEqualTo(
                 BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
@@ -559,6 +566,7 @@
         // Call onDeviceUnpaired for the one in mCachedDevices.
         mCachedDeviceManager.onDeviceUnpaired(cachedDevice2);
 
+        verify(mHearingAidDeviceManager).clearLocalDataIfNeeded(cachedDevice2);
         verify(mDevice1).removeBond();
         assertThat(cachedDevice2.getGroupId()).isEqualTo(
                 BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
@@ -611,10 +619,7 @@
 
     @Test
     public void onActiveDeviceChanged_validHiSyncId_callExpectedFunction() {
-        mHearingAidDeviceManager = spy(new HearingAidDeviceManager(mContext, mLocalBluetoothManager,
-                mCachedDeviceManager.mCachedDevices));
         doNothing().when(mHearingAidDeviceManager).onActiveDeviceChanged(any());
-        mCachedDeviceManager.mHearingAidDeviceManager = mHearingAidDeviceManager;
         when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         cachedDevice1.setHearingAidInfo(
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
index bf927a1..eb73eee 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
@@ -17,7 +17,6 @@
 
 import static android.bluetooth.BluetoothHearingAid.HI_SYNC_ID_INVALID;
 import static android.bluetooth.BluetoothLeAudio.AUDIO_LOCATION_FRONT_LEFT;
-import static android.bluetooth.BluetoothLeAudio.AUDIO_LOCATION_INVALID;
 
 import static com.android.settingslib.bluetooth.HapClientProfile.HearingAidType.TYPE_BINAURAL;
 import static com.android.settingslib.bluetooth.HapClientProfile.HearingAidType.TYPE_INVALID;
@@ -272,14 +271,14 @@
      *
      * Conditions:
      *      1) LeAudio hearing aid
-     *      2) Invalid audio location and device type
+     *      2) Invalid device type
      * Result:
      *      Do not set hearing aid info to the device.
      */
     @Test
     public void initHearingAidDeviceIfNeeded_leAudio_invalidInfo_notToSetHearingAidInfo() {
         when(mCachedDevice1.getProfiles()).thenReturn(List.of(mLeAudioProfile, mHapClientProfile));
-        when(mLeAudioProfile.getAudioLocation(mDevice1)).thenReturn(AUDIO_LOCATION_INVALID);
+        when(mLeAudioProfile.getAudioLocation(mDevice1)).thenReturn(AUDIO_LOCATION_FRONT_LEFT);
         when(mHapClientProfile.getHearingAidType(mDevice1)).thenReturn(TYPE_INVALID);
 
         mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(mCachedDevice1, null);
@@ -506,14 +505,14 @@
      *
      * Conditions:
      *      1) LeAudio hearing aid
-     *      2) Invalid audio location and device type
+     *      2) Invalid device type
      * Result:
      *      Do not set hearing aid info to the device.
      */
     @Test
     public void updateHearingAidsDevices_leAudio_invalidInfo_notToSetHearingAidInfo() {
         when(mCachedDevice1.getProfiles()).thenReturn(List.of(mLeAudioProfile, mHapClientProfile));
-        when(mLeAudioProfile.getAudioLocation(mDevice1)).thenReturn(AUDIO_LOCATION_INVALID);
+        when(mLeAudioProfile.getAudioLocation(mDevice1)).thenReturn(AUDIO_LOCATION_FRONT_LEFT);
         when(mHapClientProfile.getHearingAidType(mDevice1)).thenReturn(TYPE_INVALID);
         mCachedDeviceManager.mCachedDevices.add(mCachedDevice1);
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingDeviceLocalDataManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingDeviceLocalDataManagerTest.java
index b659c02..6d83588 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingDeviceLocalDataManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingDeviceLocalDataManagerTest.java
@@ -194,6 +194,19 @@
         verify(mListener).onDeviceLocalDataChange(TEST_ADDRESS, newData);
     }
 
+    @Test
+    public void clear_dataIsRemoved() {
+        String settings = Settings.Global.getStringForUser(mContext.getContentResolver(),
+                Settings.Global.HEARING_DEVICE_LOCAL_AMBIENT_VOLUME, UserHandle.USER_SYSTEM);
+        assertThat(settings.contains(TEST_ADDRESS)).isTrue();
+
+        HearingDeviceLocalDataManager.clear(mContext, mDevice);
+
+        settings = Settings.Global.getStringForUser(mContext.getContentResolver(),
+                Settings.Global.HEARING_DEVICE_LOCAL_AMBIENT_VOLUME, UserHandle.USER_SYSTEM);
+        assertThat(settings.contains(TEST_ADDRESS)).isFalse();
+    }
+
     private void prepareTestDataInSettings() {
         String data = generateSettingsString(TEST_ADDRESS, TEST_AMBIENT, TEST_GROUP_AMBIENT,
                 TEST_AMBIENT_CONTROL_EXPANDED);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java
index d808a25..9c34946 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java
@@ -361,6 +361,26 @@
     }
 
     @Test
+    public void onAudioDevicesAdded_doNotActivatePreexistingDevice() {
+        final AudioManager audioManager = mock(AudioManager.class);
+        InputRouteManager inputRouteManager = new InputRouteManager(mContext, audioManager);
+
+        final AudioDeviceInfo info = mockWiredHeadsetInfo();
+        InputMediaDevice device = createInputMediaDeviceFromDeviceInfo(info);
+        inputRouteManager.mInputMediaDevices.add(device);
+
+        // Trigger onAudioDevicesAdded with a device that already exists in the device list.
+        AudioDeviceInfo[] devices = {info};
+        inputRouteManager.mAudioDeviceCallback.onAudioDevicesAdded(devices);
+
+        // The device should not be activated.
+        for (@MediaRecorder.Source int preset : PRESETS) {
+            verify(audioManager, never())
+                    .setPreferredDeviceForCapturePreset(preset, getWiredHeadsetDeviceAttributes());
+        }
+    }
+
+    @Test
     public void onAudioDevicesRemoved_shouldApplyDefaultSelectedDeviceToAllPresets() {
         final AudioManager audioManager = mock(AudioManager.class);
         InputRouteManager inputRouteManager = new InputRouteManager(mContext, audioManager);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index aca2c4e..91ac34a 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -72,7 +72,6 @@
 public final class DeviceConfigService extends Binder {
     private static final List<String> sAconfigTextProtoFilesOnDevice = List.of(
             "/system/etc/aconfig_flags.pb",
-            "/system_ext/etc/aconfig_flags.pb",
             "/product/etc/aconfig_flags.pb",
             "/vendor/etc/aconfig_flags.pb");
 
@@ -133,12 +132,7 @@
             }
 
             pw.println("DeviceConfig provider: ");
-            try (ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(fd)) {
-                DeviceConfig.dump(pfd, pw, /* prefix= */ "  ", args);
-            } catch (IOException e) {
-                pw.print("IOException creating ParcelFileDescriptor: ");
-                pw.println(e);
-            }
+            DeviceConfig.dump(pw, /* prefix= */ "  ", args);
         }
 
         IContentProvider iprovider = mProvider.getIContentProvider();
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 7aed615..5cd534e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -171,7 +171,6 @@
 
     private static final List<String> sAconfigTextProtoFilesOnDevice = List.of(
             "/system/etc/aconfig_flags.pb",
-            "/system_ext/etc/aconfig_flags.pb",
             "/product/etc/aconfig_flags.pb",
             "/vendor/etc/aconfig_flags.pb");
 
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index baf829a..fb4293a 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -348,6 +348,7 @@
     <uses-permission android:name="android.permission.REQUEST_COMPANION_PROFILE_COMPUTER" />
     <uses-permission android:name="android.permission.REQUEST_COMPANION_PROFILE_AUTOMOTIVE_PROJECTION" />
     <uses-permission android:name="android.permission.REQUEST_COMPANION_PROFILE_NEARBY_DEVICE_STREAMING" />
+    <uses-permission android:name="android.permission.REQUEST_COMPANION_PROFILE_SENSOR_DEVICE_STREAMING" />
     <uses-permission android:name="android.permission.REQUEST_COMPANION_PROFILE_WATCH" />
     <uses-permission android:name="android.permission.REQUEST_COMPANION_PROFILE_GLASSES" />
     <uses-permission android:name="android.permission.REQUEST_COMPANION_SELF_MANAGED" />
@@ -740,9 +741,6 @@
     <uses-permission android:name="android.permission.USE_CUSTOM_VIRTUAL_MACHINE" />
     <uses-permission android:name="android.permission.DEBUG_VIRTUAL_MACHINE" />
 
-    <!-- Permission required to access bugreport and screenshot files created by wear.  -->
-    <uses-permission android:name="com.google.wear.permission.ACCESS_BUG_REPORT_FILES" />
-
     <!-- Permission required to run GtsAssistantTestCases -->
     <uses-permission android:name="android.permission.MANAGE_VOICE_KEYPHRASES" />
 
@@ -992,6 +990,10 @@
     <uses-permission android:name="android.permission.health.READ_SKIN_TEMPERATURE"
         android:featureFlag="android.permission.flags.replace_body_sensor_permission_enabled"/>
 
+    <!-- Permission for TestClassifier tests to get access to classifier by type -->
+    <uses-permission android:name="android.permission.ACCESS_TEXT_CLASSIFIER_BY_TYPE"
+        android:featureFlag="android.permission.flags.text_classifier_choice_api_enabled"/>
+
     <application
         android:label="@string/app_label"
         android:theme="@android:style/Theme.DeviceDefault.DayNight"
diff --git a/packages/Shell/OWNERS b/packages/Shell/OWNERS
index d4b5b862..576afdc 100644
--- a/packages/Shell/OWNERS
+++ b/packages/Shell/OWNERS
@@ -13,3 +13,7 @@
 omakoto@google.com
 michaelwr@google.com
 ronish@google.com
+
+# Wear Bugreport Owners
+ranamouawi@google.com
+yashasvig@google.com
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 11cb070..31d5bfa 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -322,6 +322,9 @@
     <!-- Query all packages on device on R+ -->
     <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
 
+    <!-- Query advanced protection state -->
+    <uses-permission android:name="android.permission.QUERY_ADVANCED_PROTECTION_MODE" />
+
     <queries>
         <intent>
             <action android:name="android.intent.action.CREATE_NOTE" />
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ne/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ne/strings.xml
index 10e36b8..9506a7e 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ne/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ne/strings.xml
@@ -11,7 +11,7 @@
     <string name="recent_apps_label" msgid="6583276995616385847">"हालै चलाइएका एप"</string>
     <string name="lockscreen_label" msgid="648347953557887087">"लक स्क्रिन"</string>
     <string name="quick_settings_label" msgid="2999117381487601865">"द्रुत सेटिङहरू"</string>
-    <string name="notifications_label" msgid="6829741046963013567">"सूचनाहरू"</string>
+    <string name="notifications_label" msgid="6829741046963013567">"नोटिफिकेसनहरू"</string>
     <string name="screenshot_label" msgid="863978141223970162">"स्क्रिनसट"</string>
     <string name="screenshot_utterance" msgid="1430760563401895074">"स्क्रिनसट लिनुहोस्"</string>
     <string name="volume_up_label" msgid="8592766918780362870">"भोल्युम बढाउनुहोस्"</string>
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index ee22915..777f6d3 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -679,7 +679,7 @@
 flag {
     name: "volume_redesign"
     namespace: "systemui"
-    description: "Enables Volume BC25 visuals update"
+    description: "Enables Volume visuals update"
     bug: "368308908"
 }
 
@@ -1325,7 +1325,7 @@
   name: "media_controls_ui_update"
   namespace: "systemui"
   description: "Enables media visuals update"
-  bug: "380053768"
+  bug: "379044958"
 }
 
 flag {
@@ -1339,16 +1339,6 @@
 }
 
 flag {
-  name: "validate_keyboard_shortcut_helper_icon_uri"
-  namespace: "systemui"
-  description: "Adds a check that the caller can access the content URI of an icon in the shortcut helper."
-  bug: "331180422"
-  metadata {
-    purpose: PURPOSE_BUGFIX
-  }
-}
-
-flag {
   name: "glanceable_hub_allow_keyguard_when_dreaming"
   namespace: "systemui"
   description: "Allows users to exit dream to keyguard with glanceable hub enabled"
@@ -1879,3 +1869,10 @@
     description: "Larger privacy indicators on large screen"
     bug: "381864715"
 }
+
+flag {
+   name: "glanceable_hub_direct_edit_mode"
+   namespace: "systemui"
+   description: "Invokes edit mode directly from long press in glanceable hub"
+   bug: "382531177"
+}
diff --git a/packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java b/packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java
index 0317d5f0..d0404ec 100644
--- a/packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java
+++ b/packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java
@@ -18,8 +18,11 @@
 
 import android.annotation.Nullable;
 import android.graphics.Canvas;
+import android.graphics.Outline;
+import android.graphics.Path;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
+import android.graphics.RectF;
 import android.os.Build;
 import android.util.Log;
 import android.view.Surface;
@@ -44,6 +47,9 @@
 public class ViewUIComponent implements UIComponent {
     private static final String TAG = "ViewUIComponent";
     private static final boolean DEBUG = Build.IS_USERDEBUG || Log.isLoggable(TAG, Log.DEBUG);
+    private final Path mClippingPath = new Path();
+    private final Outline mClippingOutline = new Outline();
+
     private final OnDrawListener mOnDrawListener = this::postDraw;
     private final View mView;
 
@@ -182,6 +188,17 @@
             canvas.scale(
                     (float) renderBounds.width() / realBounds.width(),
                     (float) renderBounds.height() / realBounds.height());
+
+            if (mView.getClipToOutline()) {
+                mView.getOutlineProvider().getOutline(mView, mClippingOutline);
+                mClippingPath.reset();
+                RectF rect = new RectF(0, 0, mView.getWidth(), mView.getHeight());
+                final float cornerRadius = mClippingOutline.getRadius();
+                mClippingPath.addRoundRect(rect, cornerRadius, cornerRadius, Path.Direction.CW);
+                mClippingPath.close();
+                canvas.clipPath(mClippingPath);
+            }
+
             canvas.saveLayerAlpha(null, (int) (255 * mView.getAlpha()));
             mView.draw(canvas);
             canvas.restore();
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 558c1eba..65cd3c7 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewTransitionAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewTransitionAnimatorController.kt
@@ -397,6 +397,10 @@
             ghostedView.visibility = View.VISIBLE
             ghostedView.invalidate()
         }
+
+        if (isEphemeral) {
+            onDispose()
+        }
     }
 
     companion object {
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/ShadeDisplayAwareDetector.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/ShadeDisplayAwareDetector.kt
index 92b6fd4..2a27a30 100644
--- a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/ShadeDisplayAwareDetector.kt
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/ShadeDisplayAwareDetector.kt
@@ -59,9 +59,9 @@
         private const val INJECT_ANNOTATION = "javax.inject.Inject"
         private const val APPLICATION_ANNOTATION =
             "com.android.systemui.dagger.qualifiers.Application"
-        private const val GLOBAL_CONFIG_ANNOTATION = "com.android.systemui.common.ui.GlobalConfig"
         private const val SHADE_DISPLAY_AWARE_ANNOTATION =
             "com.android.systemui.shade.ShadeDisplayAware"
+        private const val MAIN_ANNOTATION = "com.android.systemui.dagger.qualifiers.Main"
 
         private const val CONTEXT = "android.content.Context"
         private const val WINDOW_MANAGER = "android.view.WindowManager"
@@ -108,13 +108,10 @@
 
             // check if the parameter is a context-dependent class relevant to shade
             if (className !in CONTEXT_DEPENDENT_SHADE_CLASSES) return false
-            // check if it has @ShadeDisplayAware
-            if (hasAnnotation(SHADE_DISPLAY_AWARE_ANNOTATION)) return false
+            if (hasAnnotation(SHADE_DISPLAY_AWARE_ANNOTATION) || hasAnnotation(MAIN_ANNOTATION))
+                return false
             // check if its a @Application-annotated Context
             if (className == CONTEXT && hasAnnotation(APPLICATION_ANNOTATION)) return false
-            // check if its a @GlobalConfig-annotated ConfigurationState, ConfigurationController
-            // or ConfigurationInteractor
-            if (className in CONFIG_CLASSES && hasAnnotation(GLOBAL_CONFIG_ANNOTATION)) return false
 
             return true
         }
diff --git a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/ShadeDisplayAwareDetectorTest.kt b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/ShadeDisplayAwareDetectorTest.kt
index 79f1907..638d7cb7 100644
--- a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/ShadeDisplayAwareDetectorTest.kt
+++ b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/ShadeDisplayAwareDetectorTest.kt
@@ -73,12 +73,12 @@
             )
             .indented()
 
-    private val globalConfigStub: TestFile =
+    private val mainStub: TestFile =
         kotlin(
                 """
-                package com.android.systemui.common.ui
+                package com.android.systemui.dagger.qualifiers
 
-                @Retention(AnnotationRetention.RUNTIME) annotation class GlobalConfig
+                @Retention(AnnotationRetention.RUNTIME) annotation class Main
                 """
             )
             .indented()
@@ -119,7 +119,7 @@
             qsContext,
             shadeDisplayAwareStub,
             applicationStub,
-            globalConfigStub,
+            mainStub,
             configStateStub,
             configControllerStub,
             configInteractorStub,
@@ -308,7 +308,7 @@
     }
 
     @Test
-    fun injectedConstructor_inRelevantPackage_withGlobalConfigAnnotatedConfigurationClass() {
+    fun injectedConstructor_inRelevantPackage_withMainAnnotatedConfigurationClass() {
         lint()
             .files(
                 TestFiles.kotlin(
@@ -317,11 +317,11 @@
 
                         import javax.inject.Inject
                         import com.android.systemui.common.ui.ConfigurationState
-                        import com.android.systemui.common.ui.GlobalConfig
+                        import com.android.systemui.dagger.qualifiers.Main
 
                         class ExampleClass
                             @Inject
-                            constructor(@GlobalConfig private val configState: ConfigurationState)
+                            constructor(@Main private val configState: ConfigurationState)
                     """
                         .trimIndent()
                 ),
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
index 58b8836..029b9cd 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
@@ -38,6 +38,8 @@
 import androidx.compose.ui.input.pointer.PointerInputChange
 import androidx.compose.ui.input.pointer.PointerInputScope
 import androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNode
+import androidx.compose.ui.input.pointer.changedToDownIgnoreConsumed
+import androidx.compose.ui.input.pointer.changedToUpIgnoreConsumed
 import androidx.compose.ui.input.pointer.positionChange
 import androidx.compose.ui.input.pointer.util.VelocityTracker
 import androidx.compose.ui.input.pointer.util.addPointerInputChange
@@ -50,6 +52,7 @@
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.Velocity
 import androidx.compose.ui.util.fastAny
+import androidx.compose.ui.util.fastSumBy
 import com.android.compose.modifiers.thenIf
 import kotlin.math.sign
 import kotlinx.coroutines.CoroutineScope
@@ -65,9 +68,10 @@
 interface NestedDraggable {
     /**
      * Called when a drag is started in the given [position] (*before* dragging the touch slop) and
-     * in the direction given by [sign].
+     * in the direction given by [sign], with the given number of [pointersDown] when the touch slop
+     * was detected.
      */
-    fun onDragStarted(position: Offset, sign: Float): Controller
+    fun onDragStarted(position: Offset, sign: Float, pointersDown: Int): Controller
 
     /**
      * Whether this draggable should consume any scroll amount with the given [sign] coming from a
@@ -111,22 +115,24 @@
     draggable: NestedDraggable,
     orientation: Orientation,
     overscrollEffect: OverscrollEffect? = null,
+    enabled: Boolean = true,
 ): Modifier {
     return this.thenIf(overscrollEffect != null) { Modifier.overscroll(overscrollEffect) }
-        .then(NestedDraggableElement(draggable, orientation, overscrollEffect))
+        .then(NestedDraggableElement(draggable, orientation, overscrollEffect, enabled))
 }
 
 private data class NestedDraggableElement(
     private val draggable: NestedDraggable,
     private val orientation: Orientation,
     private val overscrollEffect: OverscrollEffect?,
+    private val enabled: Boolean,
 ) : ModifierNodeElement<NestedDraggableNode>() {
     override fun create(): NestedDraggableNode {
-        return NestedDraggableNode(draggable, orientation, overscrollEffect)
+        return NestedDraggableNode(draggable, orientation, overscrollEffect, enabled)
     }
 
     override fun update(node: NestedDraggableNode) {
-        node.update(draggable, orientation, overscrollEffect)
+        node.update(draggable, orientation, overscrollEffect, enabled)
     }
 }
 
@@ -134,6 +140,7 @@
     private var draggable: NestedDraggable,
     override var orientation: Orientation,
     private var overscrollEffect: OverscrollEffect?,
+    private var enabled: Boolean,
 ) :
     DelegatingNode(),
     PointerInputModifierNode,
@@ -167,6 +174,9 @@
      */
     private var lastFirstDown: Offset? = null
 
+    /** The number of pointers down. */
+    private var pointersDownCount = 0
+
     init {
         delegate(nestedScrollModifierNode(this, nestedScrollDispatcher))
     }
@@ -179,14 +189,22 @@
         draggable: NestedDraggable,
         orientation: Orientation,
         overscrollEffect: OverscrollEffect?,
+        enabled: Boolean,
     ) {
         this.draggable = draggable
         this.orientation = orientation
         this.overscrollEffect = overscrollEffect
+        this.enabled = enabled
 
         trackDownPositionDelegate?.resetPointerInputHandler()
         detectDragsDelegate?.resetPointerInputHandler()
         nestedScrollController?.ensureOnDragStoppedIsCalled()
+
+        if (!enabled && trackDownPositionDelegate != null) {
+            check(detectDragsDelegate != null)
+            trackDownPositionDelegate = null
+            detectDragsDelegate = null
+        }
     }
 
     override fun onPointerEvent(
@@ -194,6 +212,8 @@
         pass: PointerEventPass,
         bounds: IntSize,
     ) {
+        if (!enabled) return
+
         if (trackDownPositionDelegate == null) {
             check(detectDragsDelegate == null)
             trackDownPositionDelegate = SuspendingPointerInputModifierNode { trackDownPosition() }
@@ -221,6 +241,11 @@
 
         awaitEachGesture {
             val down = awaitFirstDown(requireUnconsumed = false)
+            check(down.position == lastFirstDown) {
+                "Position from detectDrags() is not the same as position in trackDownPosition()"
+            }
+            check(pointersDownCount == 1) { "pointersDownCount is equal to $pointersDownCount" }
+
             var overSlop = 0f
             val onTouchSlopReached = { change: PointerInputChange, over: Float ->
                 change.consume()
@@ -263,10 +288,13 @@
 
             if (drag != null) {
                 velocityTracker.resetTracking()
-
                 val sign = (drag.position - down.position).toFloat().sign
+                check(pointersDownCount > 0) { "pointersDownCount is equal to $pointersDownCount" }
                 val wrappedController =
-                    WrappedController(coroutineScope, draggable.onDragStarted(down.position, sign))
+                    WrappedController(
+                        coroutineScope,
+                        draggable.onDragStarted(down.position, sign, pointersDownCount),
+                    )
                 if (overSlop != 0f) {
                     onDrag(wrappedController, drag, overSlop, velocityTracker)
                 }
@@ -411,7 +439,22 @@
      */
 
     private suspend fun PointerInputScope.trackDownPosition() {
-        awaitEachGesture { lastFirstDown = awaitFirstDown(requireUnconsumed = false).position }
+        awaitEachGesture {
+            val down = awaitFirstDown(requireUnconsumed = false)
+            lastFirstDown = down.position
+            pointersDownCount = 1
+
+            do {
+                pointersDownCount +=
+                    awaitPointerEvent().changes.fastSumBy { change ->
+                        when {
+                            change.changedToDownIgnoreConsumed() -> 1
+                            change.changedToUpIgnoreConsumed() -> -1
+                            else -> 0
+                        }
+                    }
+            } while (pointersDownCount > 0)
+        }
     }
 
     override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
@@ -438,8 +481,14 @@
         val sign = offset.sign
         if (nestedScrollController == null && draggable.shouldConsumeNestedScroll(sign)) {
             val startedPosition = checkNotNull(lastFirstDown) { "lastFirstDown is not set" }
+
+            // TODO(b/382665591): Replace this by check(pointersDownCount > 0).
+            val pointersDown = pointersDownCount.coerceAtLeast(1)
             nestedScrollController =
-                WrappedController(coroutineScope, draggable.onDragStarted(startedPosition, sign))
+                WrappedController(
+                    coroutineScope,
+                    draggable.onDragStarted(startedPosition, sign, pointersDown),
+                )
         }
 
         val controller = nestedScrollController ?: return Offset.Zero
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/theme/Color.kt b/packages/SystemUI/compose/core/src/com/android/compose/theme/Color.kt
index a499447..fe3faaf 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/theme/Color.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/theme/Color.kt
@@ -37,4 +37,4 @@
     @ColorInt val color = ta.getColor(0, 0)
     ta.recycle()
     return Color(color)
-}
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt
index f8561b8..735ab68 100644
--- a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt
@@ -41,6 +41,7 @@
 import androidx.compose.ui.test.swipeLeft
 import androidx.compose.ui.unit.Velocity
 import com.google.common.truth.Truth.assertThat
+import kotlin.math.ceil
 import kotlinx.coroutines.awaitCancellation
 import org.junit.Ignore
 import org.junit.Rule
@@ -344,6 +345,118 @@
         assertThat(draggable.onDragStoppedCalled).isTrue()
     }
 
+    @Test
+    fun enabled() {
+        val draggable = TestDraggable()
+        var enabled by mutableStateOf(false)
+        val touchSlop =
+            rule.setContentWithTouchSlop {
+                Box(
+                    Modifier.fillMaxSize()
+                        .nestedDraggable(draggable, orientation, enabled = enabled)
+                )
+            }
+
+        assertThat(draggable.onDragStartedCalled).isFalse()
+
+        rule.onRoot().performTouchInput {
+            down(center)
+            moveBy(touchSlop.toOffset())
+        }
+
+        assertThat(draggable.onDragStartedCalled).isFalse()
+        assertThat(draggable.onDragStoppedCalled).isFalse()
+
+        enabled = true
+        rule.onRoot().performTouchInput {
+            // Release previously up finger.
+            up()
+
+            down(center)
+            moveBy(touchSlop.toOffset())
+        }
+
+        assertThat(draggable.onDragStartedCalled).isTrue()
+        assertThat(draggable.onDragStoppedCalled).isFalse()
+
+        enabled = false
+        rule.waitForIdle()
+        assertThat(draggable.onDragStoppedCalled).isTrue()
+    }
+
+    @Test
+    fun pointersDown() {
+        val draggable = TestDraggable()
+        val touchSlop =
+            rule.setContentWithTouchSlop {
+                Box(Modifier.fillMaxSize().nestedDraggable(draggable, orientation))
+            }
+
+        (1..5).forEach { nDown ->
+            rule.onRoot().performTouchInput {
+                repeat(nDown) { pointerId -> down(pointerId, center) }
+
+                moveBy(pointerId = 0, touchSlop.toOffset())
+            }
+
+            assertThat(draggable.onDragStartedPointersDown).isEqualTo(nDown)
+
+            rule.onRoot().performTouchInput {
+                repeat(nDown) { pointerId -> up(pointerId = pointerId) }
+            }
+        }
+    }
+
+    @Test
+    fun pointersDown_nestedScroll() {
+        val draggable = TestDraggable()
+        val touchSlop =
+            rule.setContentWithTouchSlop {
+                Box(
+                    Modifier.fillMaxSize()
+                        .nestedDraggable(draggable, orientation)
+                        .nestedScrollable(rememberScrollState())
+                )
+            }
+
+        (1..5).forEach { nDown ->
+            rule.onRoot().performTouchInput {
+                repeat(nDown) { pointerId -> down(pointerId, center) }
+
+                moveBy(pointerId = 0, (touchSlop + 1f).toOffset())
+            }
+
+            assertThat(draggable.onDragStartedPointersDown).isEqualTo(nDown)
+
+            rule.onRoot().performTouchInput {
+                repeat(nDown) { pointerId -> up(pointerId = pointerId) }
+            }
+        }
+    }
+
+    @Test
+    fun pointersDown_downThenUpThenDown() {
+        val draggable = TestDraggable()
+        val touchSlop =
+            rule.setContentWithTouchSlop {
+                Box(Modifier.fillMaxSize().nestedDraggable(draggable, orientation))
+            }
+
+        val slopThird = ceil(touchSlop / 3f).toOffset()
+        rule.onRoot().performTouchInput {
+            repeat(5) { down(pointerId = it, center) } // + 5
+            moveBy(pointerId = 0, slopThird)
+
+            listOf(2, 3).forEach { up(pointerId = it) } // - 2
+            moveBy(pointerId = 0, slopThird)
+
+            listOf(5, 6, 7).forEach { down(pointerId = it, center) } // + 3
+            moveBy(pointerId = 0, slopThird)
+        }
+
+        assertThat(draggable.onDragStartedPointersDown).isEqualTo(6)
+    }
+
     private fun ComposeContentTestRule.setContentWithTouchSlop(
         content: @Composable () -> Unit
     ): Float {
@@ -374,12 +487,18 @@
 
         var onDragStartedPosition = Offset.Zero
         var onDragStartedSign = 0f
+        var onDragStartedPointersDown = 0
         var onDragDelta = 0f
 
-        override fun onDragStarted(position: Offset, sign: Float): NestedDraggable.Controller {
+        override fun onDragStarted(
+            position: Offset,
+            sign: Float,
+            pointersDown: Int,
+        ): NestedDraggable.Controller {
             onDragStartedCalled = true
             onDragStartedPosition = position
             onDragStartedSign = sign
+            onDragStartedPointersDown = pointersDown
             onDragDelta = 0f
 
             onDragStarted.invoke(position, sign)
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/theme/PlatformThemeTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/theme/PlatformThemeTest.kt
index 737853b..96989a2 100644
--- a/packages/SystemUI/compose/core/tests/src/com/android/compose/theme/PlatformThemeTest.kt
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/theme/PlatformThemeTest.kt
@@ -16,8 +16,8 @@
 
 package com.android.compose.theme
 
+import android.annotation.ColorRes
 import android.content.Context
-import androidx.annotation.AttrRes
 import androidx.compose.material3.ColorScheme
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Text
@@ -70,118 +70,118 @@
         val colorValues = mutableListOf<ColorValue>()
 
         fun onLaunch(colorScheme: ColorScheme, context: Context) {
-            fun addValue(name: String, materialValue: Color, @AttrRes attr: Int) {
-                colorValues.add(ColorValue(name, materialValue, colorAttr(context, attr)))
+            fun addValue(name: String, materialValue: Color, @ColorRes color: Int) {
+                colorValues.add(ColorValue(name, materialValue, Color(context.getColor(color))))
             }
 
-            addValue("primary", colorScheme.primary, R.attr.materialColorPrimary)
-            addValue("onPrimary", colorScheme.onPrimary, R.attr.materialColorOnPrimary)
+            addValue("primary", colorScheme.primary, R.color.materialColorPrimary)
+            addValue("onPrimary", colorScheme.onPrimary, R.color.materialColorOnPrimary)
             addValue(
                 "primaryContainer",
                 colorScheme.primaryContainer,
-                R.attr.materialColorPrimaryContainer,
+                R.color.materialColorPrimaryContainer,
             )
             addValue(
                 "onPrimaryContainer",
                 colorScheme.onPrimaryContainer,
-                R.attr.materialColorOnPrimaryContainer,
+                R.color.materialColorOnPrimaryContainer,
             )
             addValue(
                 "inversePrimary",
                 colorScheme.inversePrimary,
-                R.attr.materialColorInversePrimary,
+                R.color.materialColorInversePrimary,
             )
-            addValue("secondary", colorScheme.secondary, R.attr.materialColorSecondary)
-            addValue("onSecondary", colorScheme.onSecondary, R.attr.materialColorOnSecondary)
+            addValue("secondary", colorScheme.secondary, R.color.materialColorSecondary)
+            addValue("onSecondary", colorScheme.onSecondary, R.color.materialColorOnSecondary)
             addValue(
                 "secondaryContainer",
                 colorScheme.secondaryContainer,
-                R.attr.materialColorSecondaryContainer,
+                R.color.materialColorSecondaryContainer,
             )
             addValue(
                 "onSecondaryContainer",
                 colorScheme.onSecondaryContainer,
-                R.attr.materialColorOnSecondaryContainer,
+                R.color.materialColorOnSecondaryContainer,
             )
-            addValue("tertiary", colorScheme.tertiary, R.attr.materialColorTertiary)
-            addValue("onTertiary", colorScheme.onTertiary, R.attr.materialColorOnTertiary)
+            addValue("tertiary", colorScheme.tertiary, R.color.materialColorTertiary)
+            addValue("onTertiary", colorScheme.onTertiary, R.color.materialColorOnTertiary)
             addValue(
                 "tertiaryContainer",
                 colorScheme.tertiaryContainer,
-                R.attr.materialColorTertiaryContainer,
+                R.color.materialColorTertiaryContainer,
             )
             addValue(
                 "onTertiaryContainer",
                 colorScheme.onTertiaryContainer,
-                R.attr.materialColorOnTertiaryContainer,
+                R.color.materialColorOnTertiaryContainer,
             )
-            addValue("onBackground", colorScheme.onBackground, R.attr.materialColorOnBackground)
-            addValue("surface", colorScheme.surface, R.attr.materialColorSurface)
-            addValue("onSurface", colorScheme.onSurface, R.attr.materialColorOnSurface)
+            addValue("onBackground", colorScheme.onBackground, R.color.materialColorOnBackground)
+            addValue("surface", colorScheme.surface, R.color.materialColorSurface)
+            addValue("onSurface", colorScheme.onSurface, R.color.materialColorOnSurface)
             addValue(
                 "surfaceVariant",
                 colorScheme.surfaceVariant,
-                R.attr.materialColorSurfaceVariant,
+                R.color.materialColorSurfaceVariant,
             )
             addValue(
                 "onSurfaceVariant",
                 colorScheme.onSurfaceVariant,
-                R.attr.materialColorOnSurfaceVariant,
+                R.color.materialColorOnSurfaceVariant,
             )
             addValue(
                 "inverseSurface",
                 colorScheme.inverseSurface,
-                R.attr.materialColorInverseSurface,
+                R.color.materialColorInverseSurface,
             )
             addValue(
                 "inverseOnSurface",
                 colorScheme.inverseOnSurface,
-                R.attr.materialColorInverseOnSurface,
+                R.color.materialColorInverseOnSurface,
             )
-            addValue("error", colorScheme.error, R.attr.materialColorError)
-            addValue("onError", colorScheme.onError, R.attr.materialColorOnError)
+            addValue("error", colorScheme.error, R.color.materialColorError)
+            addValue("onError", colorScheme.onError, R.color.materialColorOnError)
             addValue(
                 "errorContainer",
                 colorScheme.errorContainer,
-                R.attr.materialColorErrorContainer,
+                R.color.materialColorErrorContainer,
             )
             addValue(
                 "onErrorContainer",
                 colorScheme.onErrorContainer,
-                R.attr.materialColorOnErrorContainer,
+                R.color.materialColorOnErrorContainer,
             )
-            addValue("outline", colorScheme.outline, R.attr.materialColorOutline)
+            addValue("outline", colorScheme.outline, R.color.materialColorOutline)
             addValue(
                 "outlineVariant",
                 colorScheme.outlineVariant,
-                R.attr.materialColorOutlineVariant,
+                R.color.materialColorOutlineVariant,
             )
-            addValue("surfaceBright", colorScheme.surfaceBright, R.attr.materialColorSurfaceBright)
-            addValue("surfaceDim", colorScheme.surfaceDim, R.attr.materialColorSurfaceDim)
+            addValue("surfaceBright", colorScheme.surfaceBright, R.color.materialColorSurfaceBright)
+            addValue("surfaceDim", colorScheme.surfaceDim, R.color.materialColorSurfaceDim)
             addValue(
                 "surfaceContainer",
                 colorScheme.surfaceContainer,
-                R.attr.materialColorSurfaceContainer,
+                R.color.materialColorSurfaceContainer,
             )
             addValue(
                 "surfaceContainerHigh",
                 colorScheme.surfaceContainerHigh,
-                R.attr.materialColorSurfaceContainerHigh,
+                R.color.materialColorSurfaceContainerHigh,
             )
             addValue(
                 "surfaceContainerHighest",
                 colorScheme.surfaceContainerHighest,
-                R.attr.materialColorSurfaceContainerHighest,
+                R.color.materialColorSurfaceContainerHighest,
             )
             addValue(
                 "surfaceContainerLow",
                 colorScheme.surfaceContainerLow,
-                R.attr.materialColorSurfaceContainerLow,
+                R.color.materialColorSurfaceContainerLow,
             )
             addValue(
                 "surfaceContainerLowest",
                 colorScheme.surfaceContainerLowest,
-                R.attr.materialColorSurfaceContainerLowest,
+                R.color.materialColorSurfaceContainerLowest,
             )
         }
 
@@ -200,9 +200,9 @@
                     "MaterialTheme.colorScheme.${colorValue.name} matches attribute color"
                 )
                 .that(colorValue.materialValue)
-                .isEqualTo(colorValue.attrValue)
+                .isEqualTo(colorValue.colorValue)
         }
     }
 
-    private data class ColorValue(val name: String, val materialValue: Color, val attrValue: Color)
+    private data class ColorValue(val name: String, val materialValue: Color, val colorValue: Color)
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/Color.kt b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/Color.kt
index 64b9f2d..81ae6b3 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/Color.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/Color.kt
@@ -19,6 +19,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.ReadOnlyComposable
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.colorResource
 import com.android.compose.theme.colorAttr
 
 /** Resolves [com.android.systemui.common.shared.model.Color] into [Color] */
@@ -28,5 +29,6 @@
     return when (this) {
         is com.android.systemui.common.shared.model.Color.Attribute -> colorAttr(attribute)
         is com.android.systemui.common.shared.model.Color.Loaded -> Color(color)
+        is com.android.systemui.common.shared.model.Color.Resource -> colorResource(colorRes)
     }
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt
index 3926b32..a17a1d4 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt
@@ -23,12 +23,17 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.layout.Measurable
+import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.IntRect
+import androidx.compose.ui.unit.dp
 import androidx.compose.ui.zIndex
 import com.android.compose.animation.scene.SceneScope
 import com.android.systemui.communal.smartspace.SmartspaceInteractionHandler
 import com.android.systemui.communal.ui.compose.section.AmbientStatusBarSection
 import com.android.systemui.communal.ui.compose.section.CommunalPopupSection
+import com.android.systemui.communal.ui.compose.section.CommunalToDreamButtonSection
 import com.android.systemui.communal.ui.view.layout.sections.CommunalAppWidgetSection
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
 import com.android.systemui.keyguard.ui.composable.blueprint.BlueprintAlignmentLines
@@ -49,6 +54,7 @@
     private val ambientStatusBarSection: AmbientStatusBarSection,
     private val communalPopupSection: CommunalPopupSection,
     private val widgetSection: CommunalAppWidgetSection,
+    private val communalToDreamButtonSection: CommunalToDreamButtonSection,
 ) {
 
     @Composable
@@ -82,11 +88,13 @@
                             Modifier.element(Communal.Elements.IndicationArea).fillMaxWidth()
                         )
                     }
+                    with(communalToDreamButtonSection) { Button() }
                 },
             ) { measurables, constraints ->
                 val communalGridMeasurable = measurables[0]
                 val lockIconMeasurable = measurables[1]
                 val bottomAreaMeasurable = measurables[2]
+                val screensaverButtonMeasurable: Measurable? = measurables.getOrNull(3)
 
                 val noMinConstraints = constraints.copy(minWidth = 0, minHeight = 0)
 
@@ -101,6 +109,15 @@
 
                 val bottomAreaPlaceable = bottomAreaMeasurable.measure(noMinConstraints)
 
+                val screensaverButtonSizeInt = screensaverButtonSize.roundToPx()
+                val screensaverButtonPlaceable =
+                    screensaverButtonMeasurable?.measure(
+                        Constraints.fixed(
+                            width = screensaverButtonSizeInt,
+                            height = screensaverButtonSizeInt,
+                        )
+                    )
+
                 val communalGridPlaceable =
                     communalGridMeasurable.measure(
                         noMinConstraints.copy(maxHeight = lockIconBounds.top)
@@ -109,12 +126,22 @@
                 layout(constraints.maxWidth, constraints.maxHeight) {
                     communalGridPlaceable.place(x = 0, y = 0)
                     lockIconPlaceable.place(x = lockIconBounds.left, y = lockIconBounds.top)
-                    bottomAreaPlaceable.place(
-                        x = 0,
-                        y = constraints.maxHeight - bottomAreaPlaceable.height,
+
+                    val bottomAreaTop = constraints.maxHeight - bottomAreaPlaceable.height
+                    bottomAreaPlaceable.place(x = 0, y = bottomAreaTop)
+                    screensaverButtonPlaceable?.place(
+                        x =
+                            constraints.maxWidth -
+                                screensaverButtonSizeInt -
+                                Dimensions.ItemSpacing.roundToPx(),
+                        y = lockIconBounds.top,
                     )
                 }
             }
         }
     }
+
+    companion object {
+        val screensaverButtonSize: Dp = 64.dp
+    }
 }
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 573e5ca..315dc34 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
@@ -43,6 +43,8 @@
 import androidx.compose.foundation.focusable
 import androidx.compose.foundation.gestures.awaitFirstDown
 import androidx.compose.foundation.gestures.detectHorizontalDragGestures
+import androidx.compose.foundation.gestures.snapping.SnapPosition
+import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
@@ -151,6 +153,7 @@
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.DpSize
+import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.IntRect
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.LayoutDirection
@@ -187,6 +190,7 @@
 import com.android.systemui.communal.ui.viewmodel.ResizeInfo
 import com.android.systemui.communal.ui.viewmodel.ResizeableItemFrameViewModel
 import com.android.systemui.communal.util.DensityUtils.Companion.adjustedDp
+import com.android.systemui.communal.util.ResizeUtils.resizeOngoingItems
 import com.android.systemui.communal.widgets.SmartspaceAppWidgetHostView
 import com.android.systemui.communal.widgets.WidgetConfigurator
 import com.android.systemui.lifecycle.rememberViewModel
@@ -217,6 +221,7 @@
     var removeButtonCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
     var toolbarSize: IntSize? by remember { mutableStateOf(null) }
     var gridCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
+    var contentOffset: Offset by remember { mutableStateOf(Offset.Zero) }
 
     val gridState =
         rememberLazyGridState(viewModel.savedFirstScrollIndex, viewModel.savedFirstScrollOffset)
@@ -239,9 +244,7 @@
             initialValue = !viewModel.isEditMode
         )
 
-    val contentPadding = gridContentPadding(viewModel.isEditMode, toolbarSize)
-    val contentOffset = beforeContentPadding(contentPadding).toOffset()
-
+    val minContentPadding = gridContentPadding(viewModel.isEditMode, toolbarSize)
     ObserveScrollEffect(gridState, viewModel)
 
     val context = LocalContext.current
@@ -367,7 +370,7 @@
     ) {
         AccessibilityContainer(viewModel) {
             if (!viewModel.isEditMode && isEmptyState) {
-                EmptyStateCta(contentPadding = contentPadding, viewModel = viewModel)
+                EmptyStateCta(contentPadding = minContentPadding, viewModel = viewModel)
             } else {
                 val slideOffsetInPx =
                     with(LocalDensity.current) { Dimensions.SlideOffsetY.toPx().toInt() }
@@ -396,10 +399,11 @@
                         CommunalHubLazyGrid(
                             communalContent = communalContent,
                             viewModel = viewModel,
-                            contentPadding = contentPadding,
+                            minContentPadding = minContentPadding,
                             contentOffset = contentOffset,
                             screenWidth = screenWidth,
                             setGridCoordinates = { gridCoordinates = it },
+                            setContentOffset = { contentOffset = it },
                             updateDragPositionForRemove = { boundingBox ->
                                 val gridOffset = gridCoordinates?.positionInWindow()
                                 val removeButtonCenter =
@@ -741,27 +745,40 @@
 
 @Composable
 private fun HorizontalGridWrapper(
-    contentPadding: PaddingValues,
+    minContentPadding: PaddingValues,
     gridState: LazyGridState,
+    setContentOffset: (offset: Offset) -> Unit,
     modifier: Modifier = Modifier,
     content: LazyGridScope.(sizeInfo: SizeInfo?) -> Unit,
 ) {
     if (communalResponsiveGrid()) {
+        val flingBehavior =
+            rememberSnapFlingBehavior(lazyGridState = gridState, snapPosition = SnapPosition.Start)
         ResponsiveLazyHorizontalGrid(
             cellAspectRatio = 1.5f,
             modifier = modifier,
             state = gridState,
-            minContentPadding = contentPadding,
+            flingBehavior = flingBehavior,
+            minContentPadding = minContentPadding,
             minHorizontalArrangement = Dimensions.ItemSpacing,
             minVerticalArrangement = Dimensions.ItemSpacing,
+            setContentOffset = setContentOffset,
             content = content,
         )
     } else {
+        val layoutDirection = LocalLayoutDirection.current
+        val density = LocalDensity.current
+
+        val minStartPadding = minContentPadding.calculateStartPadding(layoutDirection)
+        val minTopPadding = minContentPadding.calculateTopPadding()
+
+        with(density) { setContentOffset(Offset(minStartPadding.toPx(), minTopPadding.toPx())) }
+
         LazyHorizontalGrid(
             modifier = modifier,
             state = gridState,
             rows = GridCells.Fixed(CommunalContentSize.FixedSize.FULL.span),
-            contentPadding = contentPadding,
+            contentPadding = minContentPadding,
             horizontalArrangement = Arrangement.spacedBy(Dimensions.ItemSpacing),
             verticalArrangement = Arrangement.spacedBy(Dimensions.ItemSpacing),
         ) {
@@ -775,13 +792,14 @@
 private fun BoxScope.CommunalHubLazyGrid(
     communalContent: List<CommunalContentModel>,
     viewModel: BaseCommunalViewModel,
-    contentPadding: PaddingValues,
+    minContentPadding: PaddingValues,
     selectedKey: State<String?>,
     screenWidth: Int,
     contentOffset: Offset,
     gridState: LazyGridState,
     contentListState: ContentListState,
     setGridCoordinates: (coordinates: LayoutCoordinates) -> Unit,
+    setContentOffset: (offset: Offset) -> Unit,
     updateDragPositionForRemove: (boundingBox: IntRect) -> Boolean,
     widgetConfigurator: WidgetConfigurator?,
     interactionHandler: RemoteViews.InteractionHandler?,
@@ -832,10 +850,19 @@
     HorizontalGridWrapper(
         modifier = gridModifier,
         gridState = gridState,
-        contentPadding = contentPadding,
+        minContentPadding = minContentPadding,
+        setContentOffset = setContentOffset,
     ) { sizeInfo ->
+        /** Override spans based on the responsive grid size */
+        val finalizedList =
+            if (sizeInfo != null) {
+                resizeOngoingItems(list, sizeInfo.gridSize.height)
+            } else {
+                list
+            }
+
         itemsIndexed(
-            items = list,
+            items = finalizedList,
             key = { _, item -> item.key },
             contentType = { _, item -> item.key },
             span = { _, item -> GridItemSpan(item.getSpanOrMax(sizeInfo?.gridSize?.height)) },
@@ -883,12 +910,12 @@
                     key = item.key,
                     currentSpan = GridItemSpan(currentItemSpan),
                     gridState = gridState,
-                    gridContentPadding = contentPadding,
+                    gridContentPadding = sizeInfo?.contentPadding ?: minContentPadding,
                     verticalArrangement =
                         Arrangement.spacedBy(
                             sizeInfo?.verticalArrangement ?: Dimensions.ItemSpacing
                         ),
-                    enabled = selected,
+                    enabled = selected && !isItemDragging,
                     alpha = { outlineAlpha },
                     modifier =
                         Modifier.requiredSize(dpSize)
@@ -926,12 +953,28 @@
                     }
                 }
             } else {
+                val itemAlpha =
+                    if (communalResponsiveGrid()) {
+                        val percentVisible by
+                            remember(gridState, index) {
+                                derivedStateOf { calculatePercentVisible(gridState, index) }
+                            }
+                        animateFloatAsState(percentVisible)
+                    } else {
+                        null
+                    }
+
                 CommunalContent(
                     model = item,
                     viewModel = viewModel,
                     size = size,
                     selected = false,
-                    modifier = Modifier.requiredSize(dpSize).animateItem(),
+                    modifier =
+                        Modifier.requiredSize(dpSize).animateItem().thenIf(
+                            communalResponsiveGrid()
+                        ) {
+                            Modifier.graphicsLayer { alpha = itemAlpha?.value ?: 1f }
+                        },
                     index = index,
                     contentListState = contentListState,
                     interactionHandler = interactionHandler,
@@ -1193,6 +1236,7 @@
         is CommunalContentModel.Smartspace -> SmartspaceContent(interactionHandler, model, modifier)
         is CommunalContentModel.Tutorial -> TutorialContent(modifier)
         is CommunalContentModel.Umo -> Umo(viewModel, sceneScope, modifier)
+        is CommunalContentModel.Spacer -> Box(Modifier.fillMaxSize())
     }
 }
 
@@ -1723,24 +1767,22 @@
     val windowMetrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context)
     val screenHeight = with(density) { windowMetrics.bounds.height().toDp() }
     val toolbarHeight = with(density) { Dimensions.ToolbarPaddingTop + toolbarSize.height.toDp() }
-    val verticalPadding =
-        ((screenHeight - toolbarHeight - hubDimensions.GridHeight + hubDimensions.GridTopSpacing) /
-                2)
-            .coerceAtLeast(Dimensions.Spacing)
-    return PaddingValues(
-        start = Dimensions.ToolbarPaddingHorizontal,
-        end = Dimensions.ToolbarPaddingHorizontal,
-        top = verticalPadding + toolbarHeight,
-        bottom = verticalPadding,
-    )
-}
-
-@Composable
-private fun beforeContentPadding(paddingValues: PaddingValues): ContentPaddingInPx {
-    return with(LocalDensity.current) {
-        ContentPaddingInPx(
-            start = paddingValues.calculateStartPadding(LocalLayoutDirection.current).toPx(),
-            top = paddingValues.calculateTopPadding().toPx(),
+    return if (communalResponsiveGrid()) {
+        PaddingValues(
+            start = Dimensions.ToolbarPaddingHorizontal,
+            end = Dimensions.ToolbarPaddingHorizontal,
+            top = hubDimensions.GridTopSpacing,
+        )
+    } else {
+        val verticalPadding =
+            ((screenHeight - toolbarHeight - hubDimensions.GridHeight +
+                    hubDimensions.GridTopSpacing) / 2)
+                .coerceAtLeast(Dimensions.Spacing)
+        PaddingValues(
+            start = Dimensions.ToolbarPaddingHorizontal,
+            end = Dimensions.ToolbarPaddingHorizontal,
+            top = verticalPadding + toolbarHeight,
+            bottom = verticalPadding,
         )
     }
 }
@@ -1760,10 +1802,6 @@
 private fun keyAtIndexIfEditable(list: List<CommunalContentModel>, index: Int): String? =
     if (index in list.indices && list[index].isWidgetContent()) list[index].key else null
 
-data class ContentPaddingInPx(val start: Float, val top: Float) {
-    fun toOffset(): Offset = Offset(start, top)
-}
-
 class Dimensions(val context: Context, val config: Configuration) {
     val GridTopSpacing: Dp
         get() {
@@ -1840,6 +1878,44 @@
         size.span
     }
 
+private fun IntRect.percentOverlap(other: IntRect): Float {
+    val intersection = intersect(other)
+    if (intersection.width < 0 || intersection.height < 0) {
+        return 0f
+    }
+    val overlapArea = intersection.width * intersection.height
+    val area = width * height
+    return overlapArea.toFloat() / area.toFloat()
+}
+
+private fun calculatePercentVisible(state: LazyGridState, index: Int): Float {
+    val viewportSize = state.layoutInfo.viewportSize
+    val visibleRect =
+        IntRect(
+            offset =
+                IntOffset(
+                    state.layoutInfo.viewportStartOffset + state.layoutInfo.beforeContentPadding,
+                    0,
+                ),
+            size =
+                IntSize(
+                    width =
+                        viewportSize.width -
+                            state.layoutInfo.beforeContentPadding -
+                            state.layoutInfo.afterContentPadding,
+                    height = viewportSize.height,
+                ),
+        )
+
+    val itemInfo = state.layoutInfo.visibleItemsInfo.find { it.index == index }
+    return if (itemInfo != null) {
+        val boundingBox = IntRect(itemInfo.offset, itemInfo.size)
+        boundingBox.percentOverlap(visibleRect)
+    } else {
+        0f
+    }
+}
+
 private object Colors {
     val DisabledColorFilter by lazy { disabledColorMatrix() }
 
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt
index 3642127..c793054 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt
@@ -35,7 +35,11 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.toComposeRect
 import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.DpSize
@@ -43,6 +47,7 @@
 import androidx.compose.ui.unit.coerceAtMost
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.times
+import androidx.window.layout.WindowMetricsCalculator
 
 /**
  * Renders a responsive [LazyHorizontalGrid] with dynamic columns and rows. Each cell will maintain
@@ -54,6 +59,7 @@
     cellAspectRatio: Float,
     modifier: Modifier = Modifier,
     state: LazyGridState = rememberLazyGridState(),
+    setContentOffset: (offset: Offset) -> Unit = {},
     minContentPadding: PaddingValues = PaddingValues(0.dp),
     minHorizontalArrangement: Dp = 0.dp,
     minVerticalArrangement: Dp = 0.dp,
@@ -68,8 +74,9 @@
             "$minHorizontalArrangement and $minVerticalArrangement, respectively."
     }
     BoxWithConstraints(modifier) {
-        val gridSize = rememberGridSize(maxWidth = maxWidth, maxHeight = maxHeight)
+        val gridSize = rememberGridSize()
         val layoutDirection = LocalLayoutDirection.current
+        val density = LocalDensity.current
 
         val minStartPadding = minContentPadding.calculateStartPadding(layoutDirection)
         val minEndPadding = minContentPadding.calculateEndPadding(layoutDirection)
@@ -124,20 +131,43 @@
         val extraWidth = maxWidth - usedWidth
         val extraHeight = maxHeight - usedHeight
 
+        // If there is a single column or single row, distribute extra space evenly across the grid.
+        // Otherwise, distribute it along the content padding to center the content.
+        val distributeHorizontalSpaceAlongGutters = gridSize.height == 1 || gridSize.width == 1
+        val evenlyDistributedWidth =
+            if (distributeHorizontalSpaceAlongGutters) {
+                extraWidth / (gridSize.width + 1)
+            } else {
+                extraWidth / 2
+            }
+
+        val finalStartPadding = minStartPadding + evenlyDistributedWidth
+        val finalEndPadding = minEndPadding + evenlyDistributedWidth
+        val finalTopPadding = minTopPadding + extraHeight / 2
+
         val finalContentPadding =
             PaddingValues(
-                start = minStartPadding + extraWidth / 2,
-                end = minEndPadding + extraWidth / 2,
-                top = minTopPadding + extraHeight / 2,
+                start = finalStartPadding,
+                end = finalEndPadding,
+                top = finalTopPadding,
                 bottom = minBottomPadding + extraHeight / 2,
             )
 
+        with(density) { setContentOffset(Offset(finalStartPadding.toPx(), finalTopPadding.toPx())) }
+
+        val horizontalArrangement =
+            if (distributeHorizontalSpaceAlongGutters) {
+                minHorizontalArrangement + evenlyDistributedWidth
+            } else {
+                minHorizontalArrangement
+            }
+
         LazyHorizontalGrid(
             rows = GridCells.Fixed(gridSize.height),
             modifier = Modifier.fillMaxSize(),
             state = state,
             contentPadding = finalContentPadding,
-            horizontalArrangement = Arrangement.spacedBy(minHorizontalArrangement),
+            horizontalArrangement = Arrangement.spacedBy(horizontalArrangement),
             verticalArrangement = Arrangement.spacedBy(minVerticalArrangement),
             flingBehavior = flingBehavior,
             userScrollEnabled = userScrollEnabled,
@@ -179,12 +209,13 @@
  * @property verticalArrangement The space between rows in the grid.
  * @property gridSize The size of the grid, in cell units.
  * @property availableHeight The maximum height an item in the grid may occupy.
+ * @property contentPadding The padding around the content of the grid.
  */
 data class SizeInfo(
     val cellSize: DpSize,
     val verticalArrangement: Dp,
     val gridSize: IntSize,
-    private val contentPadding: PaddingValues,
+    val contentPadding: PaddingValues,
     private val maxHeight: Dp,
 ) {
     val availableHeight: Dp
@@ -200,27 +231,38 @@
 }
 
 @Composable
-private fun rememberGridSize(maxWidth: Dp, maxHeight: Dp): IntSize {
+private fun rememberGridSize(): IntSize {
     val configuration = LocalConfiguration.current
     val orientation = configuration.orientation
+    val screenSize = calculateWindowSize()
 
-    return remember(orientation, maxWidth, maxHeight) {
+    return remember(orientation, screenSize) {
         if (orientation == Configuration.ORIENTATION_PORTRAIT) {
             IntSize(
-                width = calculateNumCellsWidth(maxWidth),
-                height = calculateNumCellsHeight(maxHeight),
+                width = calculateNumCellsWidth(screenSize.width),
+                height = calculateNumCellsHeight(screenSize.height),
             )
         } else {
             // In landscape we invert the rows/columns to ensure we match the same area as portrait.
             // This keeps the number of elements in the grid consistent when changing orientation.
             IntSize(
-                width = calculateNumCellsHeight(maxWidth),
-                height = calculateNumCellsWidth(maxHeight),
+                width = calculateNumCellsHeight(screenSize.width),
+                height = calculateNumCellsWidth(screenSize.height),
             )
         }
     }
 }
 
+@Composable
+fun calculateWindowSize(): DpSize {
+    // Observe view configuration changes and recalculate the size class on each change.
+    LocalConfiguration.current
+    val density = LocalDensity.current
+    val context = LocalContext.current
+    val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context)
+    return with(density) { metrics.bounds.toComposeRect().size.toDpSize() }
+}
+
 private fun calculateNumCellsWidth(width: Dp) =
     // See https://developer.android.com/develop/ui/views/layout/use-window-size-classes
     when {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalToDreamButtonSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalToDreamButtonSection.kt
new file mode 100644
index 0000000..9421596
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalToDreamButtonSection.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.ui.compose.section
+
+import androidx.compose.material3.IconButtonDefaults
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.res.stringResource
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.compose.PlatformIconButton
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
+import com.android.systemui.communal.ui.viewmodel.CommunalToDreamButtonViewModel
+import com.android.systemui.lifecycle.rememberViewModel
+import com.android.systemui.res.R
+import javax.inject.Inject
+
+class CommunalToDreamButtonSection
+@Inject
+constructor(
+    private val communalSettingsInteractor: CommunalSettingsInteractor,
+    private val viewModelFactory: CommunalToDreamButtonViewModel.Factory,
+) {
+    @Composable
+    fun Button() {
+        if (!communalSettingsInteractor.isV2FlagEnabled()) {
+            return
+        }
+
+        val viewModel =
+            rememberViewModel("CommunalToDreamButtonSection") { viewModelFactory.create() }
+        val shouldShowDreamButtonOnHub by
+            viewModel.shouldShowDreamButtonOnHub.collectAsStateWithLifecycle(false)
+
+        if (!shouldShowDreamButtonOnHub) {
+            return
+        }
+
+        PlatformIconButton(
+            onClick = { viewModel.onShowDreamButtonTap() },
+            iconResource = R.drawable.ic_screensaver_auto,
+            contentDescription =
+                stringResource(R.string.accessibility_glanceable_hub_to_dream_button),
+            colors =
+                IconButtonDefaults.filledIconButtonColors(
+                    contentColor = MaterialTheme.colorScheme.onPrimaryContainer,
+                    containerColor = MaterialTheme.colorScheme.primaryContainer,
+                ),
+        )
+    }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt
index da78eed..1cee4d6 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt
@@ -77,7 +77,7 @@
                                     resources.getDimensionPixelSize(
                                         R.dimen.keyguard_status_view_bottom_margin
                                     )
-                                }
+                                },
                             )
                 ) {
                     if (!keyguardSmartspaceViewModel.isSmartspaceEnabled) {
@@ -87,6 +87,7 @@
                     val paddingBelowClockStart =
                         dimensionResource(R.dimen.below_clock_padding_start)
                     val paddingBelowClockEnd = dimensionResource(R.dimen.below_clock_padding_end)
+                    val paddingCardHorizontal = paddingBelowClockEnd
 
                     if (keyguardSmartspaceViewModel.isDateWeatherDecoupled) {
                         Row(
@@ -96,16 +97,14 @@
                                     // All items will be constrained to be as tall as the shortest
                                     // item.
                                     .height(IntrinsicSize.Min)
-                                    .padding(
-                                        start = paddingBelowClockStart,
-                                    ),
+                                    .padding(start = paddingBelowClockStart),
                         ) {
                             Date(
                                 modifier =
                                     Modifier.burnInAware(
                                         viewModel = aodBurnInViewModel,
                                         params = burnInParams,
-                                    ),
+                                    )
                             )
                             Spacer(modifier = Modifier.width(4.dp))
                             Weather(
@@ -113,7 +112,7 @@
                                     Modifier.burnInAware(
                                         viewModel = aodBurnInViewModel,
                                         params = burnInParams,
-                                    ),
+                                    )
                             )
                         }
                     }
@@ -121,14 +120,8 @@
                     Card(
                         modifier =
                             Modifier.fillMaxWidth()
-                                .padding(
-                                    start = paddingBelowClockStart,
-                                    end = paddingBelowClockEnd,
-                                )
-                                .burnInAware(
-                                    viewModel = aodBurnInViewModel,
-                                    params = burnInParams,
-                                ),
+                                .padding(start = paddingCardHorizontal, end = paddingCardHorizontal)
+                                .burnInAware(viewModel = aodBurnInViewModel, params = burnInParams)
                     )
                 }
             }
@@ -136,9 +129,7 @@
     }
 
     @Composable
-    private fun Card(
-        modifier: Modifier = Modifier,
-    ) {
+    private fun Card(modifier: Modifier = Modifier) {
         AndroidView(
             factory = { context ->
                 FrameLayout(context).apply {
@@ -161,9 +152,7 @@
     }
 
     @Composable
-    private fun Weather(
-        modifier: Modifier = Modifier,
-    ) {
+    private fun Weather(modifier: Modifier = Modifier) {
         val isVisible by keyguardSmartspaceViewModel.isWeatherVisible.collectAsStateWithLifecycle()
         if (!isVisible) {
             return
@@ -188,9 +177,7 @@
     }
 
     @Composable
-    private fun Date(
-        modifier: Modifier = Modifier,
-    ) {
+    private fun Date(modifier: Modifier = Modifier) {
         val isVisible by keyguardSmartspaceViewModel.isDateVisible.collectAsStateWithLifecycle()
         if (!isVisible) {
             return
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt
index 35cdf81..59d0b55 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt
@@ -337,13 +337,6 @@
         check(!isAnimatingOffset()) { "SwipeAnimation.animateOffset() can only be called once" }
 
         val initialProgress = progress
-        // Skip the animation if we have already reached the target content and the overscroll does
-        // not animate anything.
-        val hasReachedTargetContent =
-            (targetContent == toContent && initialProgress >= 1f) ||
-                (targetContent == fromContent && initialProgress <= 0f)
-        val skipAnimation =
-            hasReachedTargetContent && !contentTransition.isWithinProgressRange(initialProgress)
 
         val targetContent =
             if (targetContent != currentContent && !canChangeContent(targetContent)) {
@@ -352,6 +345,14 @@
                 targetContent
             }
 
+        // Skip the animation if we have already reached the target content and the overscroll does
+        // not animate anything.
+        val hasReachedTargetContent =
+            (targetContent == toContent && initialProgress >= 1f) ||
+                (targetContent == fromContent && initialProgress <= 0f)
+        val skipAnimation =
+            hasReachedTargetContent && !contentTransition.isWithinProgressRange(initialProgress)
+
         val targetOffset =
             if (targetContent == fromContent) {
                 0f
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
index 2c8dc32..b20056d 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
@@ -42,7 +42,6 @@
 import com.android.compose.animation.scene.subjects.assertThat
 import com.android.compose.test.MonotonicClockTestScope
 import com.android.compose.test.runMonotonicClockTest
-import com.android.compose.test.transition
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Deferred
@@ -921,6 +920,28 @@
     }
 
     @Test
+    fun blockTransition_animated() = runGestureTest {
+        assertIdle(SceneA)
+        layoutState.transitions = transitions { overscrollDisabled(SceneB, Orientation.Vertical) }
+
+        // Swipe up to scene B. Overscroll 50%.
+        val dragController = onDragStarted(overSlop = up(1.5f), expectedConsumedOverSlop = up(1.0f))
+        assertTransition(currentScene = SceneA, fromScene = SceneA, toScene = SceneB, progress = 1f)
+
+        // Block the transition when the user release their finger.
+        canChangeScene = { false }
+        val velocityConsumed =
+            dragController.onDragStoppedAnimateLater(velocity = -velocityThreshold)
+
+        // Start an animation: overscroll and from 1f to 0f.
+        assertTransition(currentScene = SceneA, fromScene = SceneA, toScene = SceneB, progress = 1f)
+
+        val consumed = velocityConsumed.await()
+        assertThat(consumed).isEqualTo(-velocityThreshold)
+        assertIdle(SceneA)
+    }
+
+    @Test
     fun scrollFromIdleWithNoTargetScene_shouldUseOverscrollSpecIfAvailable() = runGestureTest {
         layoutState.transitions = transitions {
             overscroll(SceneC, Orientation.Vertical) { fade(TestElements.Foo) }
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 f1da01f..4410e15 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
@@ -771,7 +771,7 @@
 
     private fun expectedOffset(currentOffset: Dp, density: Density): Dp {
         return with(density) {
-            OffsetOverscrollEffect.computeOffset(this, currentOffset.toPx()).toDp()
+            OffsetOverscrollEffect.computeOffset(density, currentOffset.toPx()).toDp()
         }
     }
 
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/effect/OffsetOverscrollEffectTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/effect/OffsetOverscrollEffectTest.kt
index d267cc5..da8fe30 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/effect/OffsetOverscrollEffectTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/effect/OffsetOverscrollEffectTest.kt
@@ -36,6 +36,7 @@
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import kotlin.properties.Delegates
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -44,165 +45,131 @@
 class OffsetOverscrollEffectTest {
     @get:Rule val rule = createComposeRule()
 
-    private fun expectedOffset(currentOffset: Dp, density: Density): Dp {
-        return with(density) {
-            OffsetOverscrollEffect.computeOffset(this, currentOffset.toPx()).toDp()
+    private val BOX_TAG = "box"
+
+    private data class LayoutInfo(val layoutSize: Dp, val touchSlop: Float, val density: Density) {
+        fun expectedOffset(currentOffset: Dp): Dp {
+            return with(density) {
+                OffsetOverscrollEffect.computeOffset(this, currentOffset.toPx()).toDp()
+            }
         }
     }
 
+    private fun setupOverscrollableBox(
+        scrollableOrientation: Orientation,
+        overscrollEffectOrientation: Orientation = scrollableOrientation,
+    ): LayoutInfo {
+        val layoutSize: Dp = 200.dp
+        var touchSlop: Float by Delegates.notNull()
+        // The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
+        // detected as a drag event.
+        lateinit var density: Density
+        rule.setContent {
+            density = LocalDensity.current
+            touchSlop = LocalViewConfiguration.current.touchSlop
+            val overscrollEffect = rememberOffsetOverscrollEffect(overscrollEffectOrientation)
+
+            Box(
+                Modifier.overscroll(overscrollEffect)
+                    // A scrollable that does not consume the scroll gesture.
+                    .scrollable(
+                        state = rememberScrollableState { 0f },
+                        orientation = scrollableOrientation,
+                        overscrollEffect = overscrollEffect,
+                    )
+                    .size(layoutSize)
+                    .testTag(BOX_TAG)
+            )
+        }
+        return LayoutInfo(layoutSize, touchSlop, density)
+    }
+
     @Test
     fun applyVerticalOffset_duringVerticalOverscroll() {
-        // The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
-        // detected as a drag event.
-        var touchSlop = 0f
-        lateinit var density: Density
-        val layoutSize = 200.dp
+        val info = setupOverscrollableBox(scrollableOrientation = Orientation.Vertical)
 
-        rule.setContent {
-            density = LocalDensity.current
-            touchSlop = LocalViewConfiguration.current.touchSlop
-            val overscrollEffect = rememberOffsetOverscrollEffect(Orientation.Vertical)
-
-            Box(
-                Modifier.overscroll(overscrollEffect)
-                    // A scrollable that does not consume the scroll gesture.
-                    .scrollable(
-                        state = rememberScrollableState { 0f },
-                        orientation = Orientation.Vertical,
-                        overscrollEffect = overscrollEffect,
-                    )
-                    .size(layoutSize)
-                    .testTag("box")
-            )
-        }
-
-        val onBox = rule.onNodeWithTag("box")
-
-        onBox.assertTopPositionInRootIsEqualTo(0.dp)
+        rule.onNodeWithTag(BOX_TAG).assertTopPositionInRootIsEqualTo(0.dp)
 
         rule.onRoot().performTouchInput {
             down(center)
-            moveBy(Offset(0f, touchSlop + layoutSize.toPx()), delayMillis = 1_000)
+            moveBy(Offset(0f, info.touchSlop + info.layoutSize.toPx()), delayMillis = 1_000)
         }
 
-        onBox.assertTopPositionInRootIsEqualTo(expectedOffset(layoutSize, density))
+        rule
+            .onNodeWithTag(BOX_TAG)
+            .assertTopPositionInRootIsEqualTo(info.expectedOffset(info.layoutSize))
     }
 
     @Test
     fun applyNoOffset_duringHorizontalOverscroll() {
-        // The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
-        // detected as a drag event.
-        var touchSlop = 0f
-        val layoutSize = 200.dp
-
-        rule.setContent {
-            touchSlop = LocalViewConfiguration.current.touchSlop
-            val overscrollEffect = rememberOffsetOverscrollEffect(Orientation.Vertical)
-
-            Box(
-                Modifier.overscroll(overscrollEffect)
-                    // A scrollable that does not consume the scroll gesture.
-                    .scrollable(
-                        state = rememberScrollableState { 0f },
-                        orientation = Orientation.Horizontal,
-                        overscrollEffect = overscrollEffect,
-                    )
-                    .size(layoutSize)
-                    .testTag("box")
+        val info =
+            setupOverscrollableBox(
+                scrollableOrientation = Orientation.Vertical,
+                overscrollEffectOrientation = Orientation.Horizontal,
             )
-        }
 
-        val onBox = rule.onNodeWithTag("box")
-
-        onBox.assertTopPositionInRootIsEqualTo(0.dp)
+        rule.onNodeWithTag(BOX_TAG).assertTopPositionInRootIsEqualTo(0.dp)
 
         rule.onRoot().performTouchInput {
             down(center)
-            moveBy(Offset(touchSlop + layoutSize.toPx(), 0f), delayMillis = 1_000)
+            moveBy(Offset(info.touchSlop + info.layoutSize.toPx(), 0f), delayMillis = 1_000)
         }
 
-        onBox.assertTopPositionInRootIsEqualTo(0.dp)
+        rule.onNodeWithTag(BOX_TAG).assertTopPositionInRootIsEqualTo(0.dp)
     }
 
     @Test
     fun backToZero_afterOverscroll() {
-        // The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
-        // detected as a drag event.
-        var touchSlop = 0f
-        lateinit var density: Density
-        val layoutSize = 200.dp
-
-        rule.setContent {
-            density = LocalDensity.current
-            touchSlop = LocalViewConfiguration.current.touchSlop
-            val overscrollEffect = rememberOffsetOverscrollEffect(Orientation.Vertical)
-
-            Box(
-                Modifier.overscroll(overscrollEffect)
-                    // A scrollable that does not consume the scroll gesture.
-                    .scrollable(
-                        state = rememberScrollableState { 0f },
-                        orientation = Orientation.Vertical,
-                        overscrollEffect = overscrollEffect,
-                    )
-                    .size(layoutSize)
-                    .testTag("box")
-            )
-        }
-
-        val onBox = rule.onNodeWithTag("box")
+        val info = setupOverscrollableBox(scrollableOrientation = Orientation.Vertical)
 
         rule.onRoot().performTouchInput {
             down(center)
-            moveBy(Offset(0f, touchSlop + layoutSize.toPx()), delayMillis = 1_000)
+            moveBy(Offset(0f, info.touchSlop + info.layoutSize.toPx()), delayMillis = 1_000)
         }
 
-        onBox.assertTopPositionInRootIsEqualTo(expectedOffset(layoutSize, density))
+        rule
+            .onNodeWithTag(BOX_TAG)
+            .assertTopPositionInRootIsEqualTo(info.expectedOffset(info.layoutSize))
 
         rule.onRoot().performTouchInput { up() }
 
-        onBox.assertTopPositionInRootIsEqualTo(0.dp)
+        rule.onNodeWithTag(BOX_TAG).assertTopPositionInRootIsEqualTo(0.dp)
     }
 
     @Test
     fun offsetOverscroll_followTheTouchPointer() {
-        // The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
-        // detected as a drag event.
-        var touchSlop = 0f
-        lateinit var density: Density
-        val layoutSize = 200.dp
+        val info = setupOverscrollableBox(scrollableOrientation = Orientation.Vertical)
 
-        rule.setContent {
-            density = LocalDensity.current
-            touchSlop = LocalViewConfiguration.current.touchSlop
-            val overscrollEffect = rememberOffsetOverscrollEffect(Orientation.Vertical)
-
-            Box(
-                Modifier.overscroll(overscrollEffect)
-                    // A scrollable that does not consume the scroll gesture.
-                    .scrollable(
-                        state = rememberScrollableState { 0f },
-                        orientation = Orientation.Vertical,
-                        overscrollEffect = overscrollEffect,
-                    )
-                    .size(layoutSize)
-                    .testTag("box")
-            )
-        }
-
-        val onBox = rule.onNodeWithTag("box")
-
+        // First gesture, drag down.
         rule.onRoot().performTouchInput {
             down(center)
             // A full screen scroll.
-            moveBy(Offset(0f, touchSlop + layoutSize.toPx()), delayMillis = 1_000)
+            moveBy(Offset(0f, info.touchSlop + info.layoutSize.toPx()), delayMillis = 1_000)
         }
-        onBox.assertTopPositionInRootIsEqualTo(expectedOffset(layoutSize, density))
+        rule
+            .onNodeWithTag(BOX_TAG)
+            .assertTopPositionInRootIsEqualTo(info.expectedOffset(info.layoutSize))
 
         rule.onRoot().performTouchInput {
             // Reduced by half.
-            moveBy(Offset(0f, -layoutSize.toPx() / 2), delayMillis = 1_000)
+            moveBy(Offset(0f, -info.layoutSize.toPx() / 2), delayMillis = 1_000)
         }
-        onBox.assertTopPositionInRootIsEqualTo(expectedOffset(layoutSize / 2, density))
+        rule
+            .onNodeWithTag(BOX_TAG)
+            .assertTopPositionInRootIsEqualTo(info.expectedOffset(info.layoutSize / 2))
+
+        rule.onRoot().performTouchInput { up() }
+        // Animate back to 0.
+        rule.onNodeWithTag(BOX_TAG).assertTopPositionInRootIsEqualTo(0.dp)
+
+        // Second gesture, drag up.
+        rule.onRoot().performTouchInput {
+            down(center)
+            // A full screen scroll.
+            moveBy(Offset(0f, -info.touchSlop - info.layoutSize.toPx()), delayMillis = 1_000)
+        }
+        rule
+            .onNodeWithTag(BOX_TAG)
+            .assertTopPositionInRootIsEqualTo(info.expectedOffset(-info.layoutSize))
     }
 }
diff --git a/packages/SystemUI/lint-baseline.xml b/packages/SystemUI/lint-baseline.xml
index 43131b1..b0963d3 100644
--- a/packages/SystemUI/lint-baseline.xml
+++ b/packages/SystemUI/lint-baseline.xml
@@ -26857,8 +26857,8 @@
 
     <issue
         id="Overdraw"
-        message="Possible overdraw: Root element paints background `?androidprv:attr/materialColorOnSurfaceVariant` with a theme that also paints a background (inferred theme is `@style/Theme.SystemUI`)"
-        errorLine1="    android:background=&quot;?androidprv:attr/materialColorOnSurfaceVariant&quot; />"
+        message="Possible overdraw: Root element paints background `@androidprv:color/materialColorOnSurfaceVariant` with a theme that also paints a background (inferred theme is `@style/Theme.SystemUI`)"
+        errorLine1="    android:background=&quot;@androidprv:color/materialColorOnSurfaceVariant&quot; />"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="frameworks/base/packages/SystemUI/res/layout/notification_children_divider.xml"
@@ -26868,8 +26868,8 @@
 
     <issue
         id="Overdraw"
-        message="Possible overdraw: Root element paints background `?androidprv:attr/materialColorSurfaceContainerHigh` with a theme that also paints a background (inferred theme is `@style/Theme.SystemUI`)"
-        errorLine1="    android:background=&quot;?androidprv:attr/materialColorSurfaceContainerHigh&quot;"
+        message="Possible overdraw: Root element paints background `@androidprv:color/materialColorSurfaceContainerHigh` with a theme that also paints a background (inferred theme is `@style/Theme.SystemUI`)"
+        errorLine1="    android:background=&quot;@androidprv:color/materialColorSurfaceContainerHigh&quot;"
         errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="frameworks/base/packages/SystemUI/res/layout/notification_snooze.xml"
@@ -32784,1180 +32784,4 @@
             column="23"/>
     </issue>
 
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main private val resources: Resources, val theme: Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/AirplaneModeMapper.kt"
-            line="33"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapper.kt"
-            line="39"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="            @NonNull Context context,"
-        errorLine2="                             ~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java"
-            line="300"
-            column="30"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="            Context context, DeviceConfigProxy proxy) {"
-        errorLine2="                    ~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/AssistantFeedbackController.java"
-            line="75"
-            column="21"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    public AuthController(Context context,"
-        errorLine2="                                  ~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java"
-            line="716"
-            column="35"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated WindowManager, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of WindowManager is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="            @NonNull WindowManager windowManager,"
-        errorLine2="                                   ~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java"
-            line="721"
-            column="36"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    private val sysuiContext: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt"
-            line="72"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated ConfigurationController, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of ConfigurationController is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    private val configurationController: ConfigurationController,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt"
-            line="74"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main protected val resources: Resources, private val theme: Resources.Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapper.kt"
-            line="32"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="            Context context,"
-        errorLine2="                    ~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationBroadcastReceiver.java"
-            line="46"
-            column="21"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="            @Main Resources resources,"
-        errorLine2="                            ~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationDialogFactory.java"
-            line="52"
-            column="29"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    public BiometricNotificationService(@NonNull Context context,"
-        errorLine2="                                                         ~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java"
-            line="148"
-            column="58"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Application private val applicationContext: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractor.kt"
-            line="62"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Application private val applicationContext: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/BouncerRepository.kt"
-            line="37"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    c: Context,"
-        errorLine2="    ~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt"
-            line="61"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main private val resources: Resources, private val theme: Resources.Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapper.kt"
-            line="32"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main private val resources: Resources, private val theme: Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapper.kt"
-            line="33"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Application private val applicationContext: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractor.kt"
-            line="52"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Application private val applicationContext: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt"
-            line="30"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="class CustomTileStatePersisterImpl @Inject constructor(context: Context) :"
-        errorLine2="                                                       ~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/external/CustomTileStatePersister.kt"
-            line="74"
-            column="56"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main private val resources: Resources, private val theme: Resources.Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapper.kt"
-            line="32"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/DefaultTilesRepository.kt"
-            line="18"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Application context: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt"
-            line="77"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Application val context: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/DisplayStateRepository.kt"
-            line="68"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/EmergencyServicesRepository.kt"
-            line="38"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/FaceAuthAccessibilityDelegate.kt"
-            line="37"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt"
-            line="42"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Application val applicationContext: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FacePropertyRepository.kt"
-            line="95"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt"
-            line="142"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Application private val context: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt"
-            line="44"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main private val resources: Resources, private val theme: Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt"
-            line="33"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main private val resources: Resources, private val theme: Resources.Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapper.kt"
-            line="32"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="            @NonNull final Context context,"
-        errorLine2="                                   ~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java"
-            line="186"
-            column="36"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated ConfigurationController, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of ConfigurationController is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="            ConfigurationController configurationController,"
-        errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java"
-            line="192"
-            column="37"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main private val resources: Resources, private val theme: Resources.Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/HearingDevicesTileMapper.kt"
-            line="32"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="class IconBuilder @Inject constructor(private val context: Context) {"
-        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconBuilder.kt"
-            line="27"
-            column="39"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main private val resources: Resources, private val theme: Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapper.kt"
-            line="31"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated WindowManager, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of WindowManager is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    private val windowManager: WindowManager,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModel.kt"
-            line="39"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    private val context: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModel.kt"
-            line="40"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/LargeTileSpanRepository.kt"
-            line="41"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main private val resources: Resources, private val theme: Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt"
-            line="33"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated LayoutInflater, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of LayoutInflater is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    private val layoutInflater: LayoutInflater"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/MediaContainerController.kt"
-            line="29"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="class MinimumTilesResourceRepository @Inject constructor(@Main resources: Resources) :"
-        errorLine2="                                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/MinimumTilesRepository.kt"
-            line="38"
-            column="58"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main private val resources: Resources, val theme: Resources.Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapper.kt"
-            line="33"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Application private val context: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractor.kt"
-            line="38"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapper.kt"
-            line="42"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main private val resources: Resources, private val theme: Resources.Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapper.kt"
-            line="32"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    public NotificationGutsManager(Context context,"
-        errorLine2="                                           ~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java"
-            line="137"
-            column="44"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt"
-            line="47"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt"
-            line="53"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(val context: Context) {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt"
-            line="27"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated ConfigurationController, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of ConfigurationController is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="            ConfigurationController configurationController,"
-        errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java"
-            line="737"
-            column="37"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt"
-            line="63"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="        Builder(@Main Resources resources, ViewConfiguration viewConfiguration,"
-        errorLine2="                                ~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java"
-            line="563"
-            column="33"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main private val resources: Resources, private val theme: Resources.Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapper.kt"
-            line="32"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    public PackageManagerAdapter(Context context) {"
-        errorLine2="                                         ~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/external/PackageManagerAdapter.java"
-            line="45"
-            column="42"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/PaginatedGridRepository.kt"
-            line="36"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    private val context: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt"
-            line="74"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    private val context: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt"
-            line="41"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Application private val context: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt"
-            line="82"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main private val resources: Resources, private val theme: Resources.Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapper.kt"
-            line="32"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QSColumnsRepository.kt"
-            line="36"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="        Factory(Context context, QSCustomizerController qsCustomizerController) {"
-        errorLine2="                        ~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java"
-            line="99"
-            column="25"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepository.kt"
-            line="32"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main private val resources: Resources, private val theme: Resources.Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapper.kt"
-            line="33"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt"
-            line="36"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt"
-            line="47"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt"
-            line="36"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddable.kt"
-            line="51"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main private val resources: Resources, private val theme: Resources.Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/ScreenRecordTileMapper.kt"
-            line="33"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated LayoutInflater, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of LayoutInflater is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    private val layoutInflater: LayoutInflater,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt"
-            line="43"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    context: Context"
-        errorLine2="    ~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt"
-            line="35"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Application private val applicationContext: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt"
-            line="63"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Application private val applicationContext: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt"
-            line="53"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    private val context: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/SideFpsSensorInteractor.kt"
-            line="51"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated WindowManager, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of WindowManager is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    windowManager: WindowManager,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/SideFpsSensorInteractor.kt"
-            line="53"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Application private val applicationContext: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractor.kt"
-            line="60"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractor.kt"
-            line="65"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Resources is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/SimBouncerRepository.kt"
-            line="91"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(context: Context, val shadeViewController: ShadeViewController) {"
-        errorLine2="            ~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/shade/StatusBarLongPressGestureDetector.kt"
-            line="30"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/StockTilesRepository.kt"
-            line="31"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    private val context: Context"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolver.kt"
-            line="33"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/TileSpecRepository.kt"
-            line="95"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Resources is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegate.kt"
-            line="33"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Context is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Application private val context: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt"
-            line="49"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated ConfigurationController, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of ConfigurationController is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    private val configurationController: ConfigurationController,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractor.kt"
-            line="43"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="constructor(@Main private val resources: Resources, private val theme: Theme) :"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapper.kt"
-            line="37"
-            column="13"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of Resources is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapper.kt"
-            line="36"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window&#xA;should use ShadeDisplayAware-annotated ConfigurationInteractor, as the shade might move between windows, and only&#xA;@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so&#xA;might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).&#xA;If the usage of ConfigurationInteractor is not related to display specific configuration or UI, then there is&#xA;technically no need to use the annotation, and you can annotate the class with&#xA;@SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @GlobalConfig configurationInteractor: ConfigurationInteractor,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModel.kt"
-            line="43"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    public AuthController(Context context,"
-        errorLine2="                                  ~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java"
-            line="716"
-            column="35"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated WindowManager, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of WindowManager is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="            @NonNull WindowManager windowManager,"
-        errorLine2="                                   ~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java"
-            line="721"
-            column="36"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    private val sysuiContext: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt"
-            line="72"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated ConfigurationController, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of ConfigurationController is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    private val configurationController: ConfigurationController,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt"
-            line="74"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="            Context context,"
-        errorLine2="                    ~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationBroadcastReceiver.java"
-            line="46"
-            column="21"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Resources is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="            @Main Resources resources,"
-        errorLine2="                            ~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationDialogFactory.java"
-            line="52"
-            column="29"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    public BiometricNotificationService(@NonNull Context context,"
-        errorLine2="                                                         ~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java"
-            line="148"
-            column="58"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    c: Context,"
-        errorLine2="    ~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt"
-            line="61"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Resources is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/EmergencyServicesRepository.kt"
-            line="39"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Resources is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/FaceAuthAccessibilityDelegate.kt"
-            line="37"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Resources is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt"
-            line="42"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="            @NonNull final Context context,"
-        errorLine2="                                   ~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java"
-            line="186"
-            column="36"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="class IconBuilder @Inject constructor(private val context: Context) {"
-        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconBuilder.kt"
-            line="27"
-            column="39"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated WindowManager, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of WindowManager is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    private val windowManager: WindowManager,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModel.kt"
-            line="40"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Resources is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt"
-            line="53"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Resources is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    @Main private val resources: Resources,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddable.kt"
-            line="51"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    private val context: Context,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/SideFpsSensorInteractor.kt"
-            line="51"
-            column="5"/>
-    </issue>
-
-    <issue
-        id="ShadeDisplayAwareContextChecker"
-        message="UI elements of the shade window should use ShadeDisplayAware-annotated WindowManager, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of WindowManager is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint(&quot;ShadeDisplayAwareContextChecker&quot;)/@Suppress(&quot;ShadeDisplayAwareContextChecker&quot;)"
-        errorLine1="    windowManager: WindowManager,"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/SideFpsSensorInteractor.kt"
-            line="53"
-            column="5"/>
-
 </issues>
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java
index fa8cdcc..80de087 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java
@@ -24,6 +24,7 @@
 import android.platform.test.annotations.EnableFlags;
 import android.testing.TestableLooper;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
@@ -39,6 +40,7 @@
 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;
 
@@ -54,11 +56,15 @@
     @Rule
     public MockitoRule mockito = MockitoJUnit.rule();
 
+    @Mock
+    private AccessibilityManager mAccessibilityManager;
+
     @Before
     public void setUp() throws Exception {
         final WindowManager stubWindowManager = mContext.getSystemService(WindowManager.class);
         final SecureSettings mockSecureSettings = TestUtils.mockSecureSettings();
-        final MenuViewModel stubMenuViewModel = new MenuViewModel(mContext, mockSecureSettings);
+        final MenuViewModel stubMenuViewModel = new MenuViewModel(mContext, mAccessibilityManager,
+                mockSecureSettings);
         final MenuViewAppearance stubMenuViewAppearance = new MenuViewAppearance(mContext,
                 stubWindowManager);
         final MenuView stubMenuView = spy(new MenuView(mContext, stubMenuViewModel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepositoryTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepositoryTest.java
index 7e4b6f9..24f3a29 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepositoryTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepositoryTest.java
@@ -16,11 +16,16 @@
 
 package com.android.systemui.accessibility.floatingmenu;
 
+import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
+
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 
+import android.content.Context;
 import android.content.res.Configuration;
+import android.view.accessibility.AccessibilityManager;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
@@ -28,6 +33,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.util.settings.SecureSettings;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -36,6 +42,8 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Locale;
 
 /** Tests for {@link MenuInfoRepository}. */
@@ -46,16 +54,30 @@
     public MockitoRule mockito = MockitoJUnit.rule();
 
     @Mock
+    private AccessibilityManager mAccessibilityManager;
+
+    @Mock
     private MenuInfoRepository.OnSettingsContentsChanged mMockSettingsContentsChanged;
     @Mock
     private SecureSettings mSecureSettings;
 
     private MenuInfoRepository mMenuInfoRepository;
+    private final List<String> mShortcutTargets = new ArrayList<>();
 
     @Before
     public void setUp() {
-        mMenuInfoRepository = new MenuInfoRepository(mContext, mMockSettingsContentsChanged,
-                mSecureSettings);
+        mContext.addMockSystemService(Context.ACCESSIBILITY_SERVICE, mAccessibilityManager);
+        mShortcutTargets.add(MAGNIFICATION_CONTROLLER_NAME);
+        doReturn(mShortcutTargets).when(mAccessibilityManager).getAccessibilityShortcutTargets(
+                anyInt());
+
+        mMenuInfoRepository = new MenuInfoRepository(mContext, mAccessibilityManager,
+                mMockSettingsContentsChanged, mSecureSettings);
+    }
+
+    @After
+    public void tearDown() {
+        mShortcutTargets.clear();
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java
index 1f48bec..157cccc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java
@@ -83,7 +83,8 @@
         final WindowManager stubWindowManager = mContext.getSystemService(WindowManager.class);
         final MenuViewAppearance stubMenuViewAppearance = new MenuViewAppearance(mContext,
                 stubWindowManager);
-        final MenuViewModel stubMenuViewModel = new MenuViewModel(mContext, mSecureSettings);
+        final MenuViewModel stubMenuViewModel = new MenuViewModel(mContext, mAccessibilityManager,
+                mSecureSettings);
 
         final int halfScreenHeight =
                 stubWindowManager.getCurrentWindowMetrics().getBounds().height() / 2;
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java
index f7b81cc..46f076a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java
@@ -33,6 +33,7 @@
 import android.testing.TestableLooper;
 import android.view.MotionEvent;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
 
 import androidx.dynamicanimation.animation.DynamicAnimation;
 import androidx.recyclerview.widget.RecyclerView;
@@ -52,6 +53,7 @@
 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;
 
@@ -78,11 +80,15 @@
     @Rule
     public MockitoRule mockito = MockitoJUnit.rule();
 
+    @Mock
+    private AccessibilityManager mAccessibilityManager;
+
     @Before
     public void setUp() throws Exception {
         final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
         final SecureSettings secureSettings = TestUtils.mockSecureSettings();
-        final MenuViewModel stubMenuViewModel = new MenuViewModel(mContext, secureSettings);
+        final MenuViewModel stubMenuViewModel = new MenuViewModel(mContext, mAccessibilityManager,
+                secureSettings);
         final MenuViewAppearance stubMenuViewAppearance = new MenuViewAppearance(mContext,
                 windowManager);
         mStubMenuView = new MenuView(mContext, stubMenuViewModel, stubMenuViewAppearance,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java
index c1708d1..ee8ce17 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java
@@ -32,6 +32,7 @@
 import android.platform.test.annotations.EnableFlags;
 import android.testing.TestableLooper;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
@@ -48,6 +49,7 @@
 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;
 
@@ -66,6 +68,9 @@
     @Rule
     public MockitoRule mockito = MockitoJUnit.rule();
 
+    @Mock
+    private AccessibilityManager mAccessibilityManager;
+
     private SysuiTestableContext mSpyContext;
 
     @Before
@@ -84,7 +89,8 @@
         doNothing().when(mSpyContext).startActivity(any());
 
         final SecureSettings secureSettings = TestUtils.mockSecureSettings();
-        final MenuViewModel stubMenuViewModel = new MenuViewModel(mContext, secureSettings);
+        final MenuViewModel stubMenuViewModel = new MenuViewModel(mContext, mAccessibilityManager,
+                secureSettings);
         final WindowManager stubWindowManager = mContext.getSystemService(WindowManager.class);
         mStubMenuViewAppearance = new MenuViewAppearance(mSpyContext, stubWindowManager);
         mMenuView = spy(new MenuView(mSpyContext, stubMenuViewModel, mStubMenuViewAppearance,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
index d75c013..ab93659 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
@@ -1589,7 +1589,8 @@
             val logoInfo by collectLastValue(kosmos.promptViewModel.logoInfo)
             assertThat(logoInfo).isNotNull()
             assertThat(logoInfo!!.first).isEqualTo(defaultLogoIconWithBadge)
-            assertThat(logoInfo!!.second).isEqualTo(defaultLogoDescriptionWithBadge)
+            // Logo label does not use badge info.
+            assertThat(logoInfo!!.second).isEqualTo(defaultLogoDescriptionFromAppInfo)
         }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
index 84d062a..831012c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
@@ -30,7 +30,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.airbnb.lottie.model.KeyPath
-import com.android.settingslib.Utils
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider
 import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
@@ -77,20 +76,14 @@
 
     private val contextDisplayInfo = DisplayInfo()
 
-    private val indicatorColor =
-        Utils.getColorAttrDefaultColor(
-            context,
-            com.android.internal.R.attr.materialColorPrimaryFixed,
+    private val indicatorColor = context.getColor(
+            com.android.internal.R.color.materialColorPrimaryFixed,
         )
-    private val outerRimColor =
-        Utils.getColorAttrDefaultColor(
-            context,
-            com.android.internal.R.attr.materialColorPrimaryFixedDim,
+    private val outerRimColor = context.getColor(
+            com.android.internal.R.color.materialColorPrimaryFixedDim,
         )
-    private val chevronFill =
-        Utils.getColorAttrDefaultColor(
-            context,
-            com.android.internal.R.attr.materialColorOnPrimaryFixed,
+    private val chevronFill = context.getColor(
+            com.android.internal.R.color.materialColorOnPrimaryFixed,
         )
     private val color_blue400 =
         context.getColor(com.android.settingslib.color.R.color.settingslib_color_blue400)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModelTest.kt
new file mode 100644
index 0000000..8820685
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModelTest.kt
@@ -0,0 +1,104 @@
+/*
+ * 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.ui.viewmodel
+
+import android.platform.test.annotations.EnableFlags
+import android.service.dream.dreamManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
+import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runCurrent
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.lifecycle.activateIn
+import com.android.systemui.statusbar.policy.batteryController
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@EnableFlags(FLAG_GLANCEABLE_HUB_V2)
+@RunWith(AndroidJUnit4::class)
+class CommunalToDreamButtonViewModelTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val underTest: CommunalToDreamButtonViewModel by lazy {
+        kosmos.communalToDreamButtonViewModel
+    }
+
+    @Before
+    fun setUp() {
+        kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
+        underTest.activateIn(testScope)
+    }
+
+    @Test
+    fun shouldShowDreamButtonOnHub_trueWhenCanDream() =
+        with(kosmos) {
+            runTest {
+                whenever(dreamManager.canStartDreaming(any())).thenReturn(true)
+                whenever(batteryController.isPluggedIn()).thenReturn(true)
+
+                val shouldShowButton by collectLastValue(underTest.shouldShowDreamButtonOnHub)
+                assertThat(shouldShowButton).isTrue()
+            }
+        }
+
+    @Test
+    fun shouldShowDreamButtonOnHub_falseWhenCannotDream() =
+        with(kosmos) {
+            runTest {
+                whenever(dreamManager.canStartDreaming(any())).thenReturn(false)
+                whenever(batteryController.isPluggedIn()).thenReturn(true)
+
+                val shouldShowButton by collectLastValue(underTest.shouldShowDreamButtonOnHub)
+                assertThat(shouldShowButton).isFalse()
+            }
+        }
+
+    @Test
+    fun shouldShowDreamButtonOnHub_falseWhenNotPluggedIn() =
+        with(kosmos) {
+            runTest {
+                whenever(dreamManager.canStartDreaming(any())).thenReturn(true)
+                whenever(batteryController.isPluggedIn()).thenReturn(false)
+
+                val shouldShowButton by collectLastValue(underTest.shouldShowDreamButtonOnHub)
+                assertThat(shouldShowButton).isFalse()
+            }
+        }
+
+    @Test
+    fun onShowDreamButtonTap_startsDream() =
+        with(kosmos) {
+            runTest {
+                underTest.onShowDreamButtonTap()
+                runCurrent()
+
+                verify(dreamManager).startDream()
+            }
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/util/ResizeUtilsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/util/ResizeUtilsTest.kt
new file mode 100644
index 0000000..b0f4803
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/util/ResizeUtilsTest.kt
@@ -0,0 +1,222 @@
+/*
+ * 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.util
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.domain.model.CommunalContentModel
+import com.android.systemui.communal.shared.model.CommunalContentSize
+import com.android.systemui.communal.util.ResizeUtils.resizeOngoingItems
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ResizeUtilsTest : SysuiTestCase() {
+    private val mockWidget =
+        mock<CommunalContentModel.WidgetContent.Widget> {
+            on { size } doReturn CommunalContentSize.Responsive(1)
+        }
+
+    @Test
+    fun noOngoingContent() {
+        val list = listOf(mockWidget)
+        val resized = resizeOngoingItems(list = list, numRows = 2)
+
+        assertThat(resized).containsExactly(mockWidget)
+    }
+
+    @Test
+    fun singleOngoingContent_singleRowGrid() {
+        val list = createOngoingListWithSize(1) + listOf(mockWidget)
+        val resized = resizeOngoingItems(list = list, numRows = 1)
+
+        assertThat(resized.map { it.size })
+            .containsExactly(CommunalContentSize.Responsive(1), mockWidget.size)
+            .inOrder()
+    }
+
+    @Test
+    fun singleOngoingContent_twoRowGrid() {
+        val list = createOngoingListWithSize(1) + listOf(mockWidget)
+        val resized = resizeOngoingItems(list = list, numRows = 2)
+
+        assertThat(resized.map { it.size })
+            .containsExactly(CommunalContentSize.Responsive(2), mockWidget.size)
+            .inOrder()
+    }
+
+    @Test
+    fun singleOngoingContent_threeRowGrid() {
+        val list = createOngoingListWithSize(1) + listOf(mockWidget)
+        val resized = resizeOngoingItems(list = list, numRows = 3)
+
+        assertThat(resized.map { it.size })
+            .containsExactly(
+                CommunalContentSize.Responsive(2),
+                CommunalContentSize.Responsive(1),
+                mockWidget.size,
+            )
+            .inOrder()
+        // A spacer should be added as the second element to avoid mixing widget content
+        // with ongoing content.
+        assertThat(resized[1]).isInstanceOf(CommunalContentModel.Spacer::class.java)
+    }
+
+    @Test
+    fun twoOngoingContent_singleRowGrid() {
+        val list = createOngoingListWithSize(2) + listOf(mockWidget)
+        val resized = resizeOngoingItems(list = list, numRows = 1)
+
+        assertThat(resized.map { it.size })
+            .containsExactly(
+                CommunalContentSize.Responsive(1),
+                CommunalContentSize.Responsive(1),
+                mockWidget.size,
+            )
+            .inOrder()
+    }
+
+    @Test
+    fun twoOngoingContent_twoRowGrid() {
+        val list = createOngoingListWithSize(2) + listOf(mockWidget)
+        val resized = resizeOngoingItems(list = list, numRows = 2)
+
+        assertThat(resized.map { it.size })
+            .containsExactly(
+                CommunalContentSize.Responsive(1),
+                CommunalContentSize.Responsive(1),
+                mockWidget.size,
+            )
+            .inOrder()
+    }
+
+    @Test
+    fun twoOngoingContent_threeRowGrid() {
+        val list = createOngoingListWithSize(2) + listOf(mockWidget)
+        val resized = resizeOngoingItems(list = list, numRows = 3)
+
+        assertThat(resized.map { it.size })
+            .containsExactly(
+                CommunalContentSize.Responsive(2),
+                CommunalContentSize.Responsive(1),
+                mockWidget.size,
+            )
+            .inOrder()
+    }
+
+    @Test
+    fun threeOngoingContent_singleRowGrid() {
+        val list = createOngoingListWithSize(3) + listOf(mockWidget)
+        val resized = resizeOngoingItems(list = list, numRows = 1)
+
+        assertThat(resized.map { it.size })
+            .containsExactly(
+                CommunalContentSize.Responsive(1),
+                CommunalContentSize.Responsive(1),
+                CommunalContentSize.Responsive(1),
+                mockWidget.size,
+            )
+            .inOrder()
+    }
+
+    @Test
+    fun threeOngoingContent_twoRowGrid() {
+        val list = createOngoingListWithSize(3) + listOf(mockWidget)
+        val resized = resizeOngoingItems(list = list, numRows = 2)
+
+        assertThat(resized.map { it.size })
+            .containsExactly(
+                CommunalContentSize.Responsive(2),
+                CommunalContentSize.Responsive(1),
+                CommunalContentSize.Responsive(1),
+                mockWidget.size,
+            )
+            .inOrder()
+    }
+
+    @Test
+    fun threeOngoingContent_threeRowGrid() {
+        val list = createOngoingListWithSize(3) + listOf(mockWidget)
+        val resized = resizeOngoingItems(list = list, numRows = 3)
+
+        assertThat(resized.map { it.size })
+            .containsExactly(
+                CommunalContentSize.Responsive(1),
+                CommunalContentSize.Responsive(1),
+                CommunalContentSize.Responsive(1),
+                mockWidget.size,
+            )
+            .inOrder()
+    }
+
+    @Test
+    fun fourOngoingContent_singleRowGrid() {
+        val list = createOngoingListWithSize(4) + listOf(mockWidget)
+        val resized = resizeOngoingItems(list = list, numRows = 1)
+
+        assertThat(resized.map { it.size })
+            .containsExactly(
+                CommunalContentSize.Responsive(1),
+                CommunalContentSize.Responsive(1),
+                CommunalContentSize.Responsive(1),
+                CommunalContentSize.Responsive(1),
+                mockWidget.size,
+            )
+            .inOrder()
+    }
+
+    @Test
+    fun fourOngoingContent_twoRowGrid() {
+        val list = createOngoingListWithSize(4) + listOf(mockWidget)
+        val resized = resizeOngoingItems(list = list, numRows = 2)
+
+        assertThat(resized.map { it.size })
+            .containsExactly(
+                CommunalContentSize.Responsive(1),
+                CommunalContentSize.Responsive(1),
+                CommunalContentSize.Responsive(1),
+                CommunalContentSize.Responsive(1),
+                mockWidget.size,
+            )
+            .inOrder()
+    }
+
+    @Test
+    fun fourOngoingContent_threeRowGrid() {
+        val list = createOngoingListWithSize(4) + listOf(mockWidget)
+        val resized = resizeOngoingItems(list = list, numRows = 3)
+
+        assertThat(resized.map { it.size })
+            .containsExactly(
+                CommunalContentSize.Responsive(2),
+                CommunalContentSize.Responsive(1),
+                CommunalContentSize.Responsive(2),
+                CommunalContentSize.Responsive(1),
+                mockWidget.size,
+            )
+            .inOrder()
+    }
+
+    private fun createOngoingListWithSize(size: Int): List<CommunalContentModel.Ongoing> {
+        return List(size) { CommunalContentModel.Umo(createdTimestampMillis = 100) }
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
index 763ea39..9d711ab 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
@@ -19,6 +19,7 @@
 import android.content.ComponentName
 import android.content.pm.UserInfo
 import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
 import android.platform.test.flag.junit.FlagsParameterization
 import android.provider.Settings
 import android.widget.RemoteViews
@@ -26,6 +27,7 @@
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
 import com.android.systemui.Flags.FLAG_COMMUNAL_RESPONSIVE_GRID
+import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_DIRECT_EDIT_MODE
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.communal.data.model.CommunalSmartspaceTimer
 import com.android.systemui.communal.data.repository.FakeCommunalMediaRepository
@@ -101,6 +103,7 @@
 import org.mockito.Mockito
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
 import org.mockito.kotlin.atLeastOnce
 import org.mockito.kotlin.eq
 import org.mockito.kotlin.mock
@@ -442,6 +445,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_GLANCEABLE_HUB_DIRECT_EDIT_MODE)
     fun customizeWidgetButton_showsThenHidesAfterTimeout() =
         testScope.runTest {
             tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
@@ -455,6 +459,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_GLANCEABLE_HUB_DIRECT_EDIT_MODE)
     fun customizeWidgetButton_onDismiss_hidesImmediately() =
         testScope.runTest {
             tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
@@ -468,6 +473,14 @@
         }
 
     @Test
+    @EnableFlags(FLAG_GLANCEABLE_HUB_DIRECT_EDIT_MODE)
+    fun longClickDirectlyStartsEditMode() =
+        testScope.runTest {
+            underTest.onLongClick()
+            verify(communalInteractor).showWidgetEditor(any())
+        }
+
+    @Test
     fun canChangeScene_shadeNotExpanded() =
         testScope.runTest {
             // On keyguard without any shade expansion.
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/OWNERS b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/OWNERS
new file mode 100644
index 0000000..2355c48
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 1562219
+chrisgollner@google.com
+jmokut@google.com
\ No newline at end of file
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
index 92c76ff..7dc7016 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
@@ -40,7 +40,6 @@
 import com.android.systemui.keyboard.shortcut.shared.model.Shortcut
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.AppCategories
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MultiTasking
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.System
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
@@ -543,27 +542,17 @@
             simpleShortcutCategory(
                 MultiTasking,
                 "Split screen",
-                "Switch from split screen to full screen",
+                "Switch to full screen",
             ),
             simpleShortcutCategory(
                 MultiTasking,
                 "Split screen",
-                "Use split screen with current app on the left",
+                "Use split screen with app on the left",
             ),
             simpleShortcutCategory(
                 MultiTasking,
                 "Split screen",
-                "Switch to app on left or above while using split screen",
-            ),
-            simpleShortcutCategory(
-                MultiTasking,
-                "Split screen",
-                "Use split screen with current app on the right",
-            ),
-            simpleShortcutCategory(
-                MultiTasking,
-                "Split screen",
-                "Switch to app on right or below while using split screen",
+                "Use split screen with app on the right",
             ),
             simpleShortcutCategory(System, "System controls", "Show shortcuts"),
             simpleShortcutCategory(System, "System controls", "View recent apps"),
@@ -595,15 +584,9 @@
                 keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_LEFT
             ),
             simpleInputGestureData(
-                keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_LEFT
-            ),
-            simpleInputGestureData(
                 keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_RIGHT
             ),
             simpleInputGestureData(
-                keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_RIGHT
-            ),
-            simpleInputGestureData(
                 keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER
             ),
             simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS),
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelTest.kt
index 5e9badc..4dbe7c8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelTest.kt
@@ -28,6 +28,7 @@
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.shadeTestUtil
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
@@ -171,8 +172,10 @@
             // WHEN transition is cancelled
             repository.sendTransitionStep(step(.1f, TransitionState.CANCELED))
 
-            // THEN alpha is immediately set to 1f (expected lockscreen alpha state)
-            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(1f)
+            // THEN alpha updates according to whether the scene framework is enabled (CANCELED is
+            // ignored when the scene framework is enabled).
+            assertThat(deviceEntryBackgroundViewAlpha)
+                .isEqualTo(if (SceneContainerFlag.isEnabled) 0f else 1f)
         }
 
     @Test
@@ -195,14 +198,14 @@
 
     private fun step(
         value: Float,
-        state: TransitionState = TransitionState.RUNNING
+        state: TransitionState = TransitionState.RUNNING,
     ): TransitionStep {
         return TransitionStep(
             from = KeyguardState.AOD,
             to = KeyguardState.LOCKSCREEN,
             value = value,
             transitionState = state,
-            ownerName = "AodToLockscreenTransitionViewModelTest"
+            ownerName = "AodToLockscreenTransitionViewModelTest",
         )
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
index d0da2e9..576795d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
@@ -38,6 +38,7 @@
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.res.R
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.ShadeTestUtil
 import com.android.systemui.shade.shadeTestUtil
 import com.android.systemui.testKosmos
@@ -178,11 +179,13 @@
                     ),
                 testScope = testScope,
             )
-            assertThat(values.size).isEqualTo(3)
+            assertThat(values.size).isEqualTo(if (SceneContainerFlag.isEnabled) 2 else 3)
             values.forEach { assertThat(it).isIn(Range.closed(0f, 100f)) }
 
-            // Cancel will reset the translation
-            assertThat(values[2]).isEqualTo(0)
+            // When the scene framework is not enabled, cancel will reset the translation
+            if (!SceneContainerFlag.isEnabled) {
+                assertThat(values.last()).isEqualTo(0f)
+            }
         }
 
     @Test
@@ -242,8 +245,9 @@
             // WHEN transition is canceled
             repository.sendTransitionStep(step(1f, TransitionState.CANCELED))
 
-            // THEN alpha is immediately set to 0f
-            assertThat(actual).isEqualTo(0f)
+            // THEN alpha updates according to whether the scene framework is enabled (CANCELED is
+            // ignored when the scene framework is enabled).
+            assertThat(actual).isEqualTo(if (SceneContainerFlag.isEnabled) 1f else 0f)
         }
 
     private fun step(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/FgsManagerControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/FgsManagerControllerTest.java
index 0356422..004aeb0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/FgsManagerControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/FgsManagerControllerTest.java
@@ -122,7 +122,7 @@
         mSystemClock = new FakeSystemClock();
         mMainExecutor = new FakeExecutor(mSystemClock);
         mBackgroundExecutor = new FakeExecutor(mSystemClock);
-        when(mSystemUIDialogFactory.create()).thenReturn(mSystemUIDialog);
+        when(mSystemUIDialogFactory.create(eq(mContext))).thenReturn(mSystemUIDialog);
 
         mUserProfiles = new ArrayList<>();
         Mockito.doReturn(mUserProfiles).when(mUserTracker).getUserProfiles();
@@ -346,6 +346,7 @@
                 SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_USER_VISIBLE_JOBS,
                 "true", false);
         FgsManagerController fmc = new FgsManagerControllerImpl(
+                mContext,
                 mContext.getResources(),
                 mMainExecutor,
                 mBackgroundExecutor,
@@ -373,6 +374,7 @@
                 SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_USER_VISIBLE_JOBS,
                 "false", false);
         fmc = new FgsManagerControllerImpl(
+                mContext,
                 mContext.getResources(),
                 mMainExecutor,
                 mBackgroundExecutor,
@@ -485,6 +487,7 @@
                 ArgumentCaptor.forClass(BroadcastReceiver.class);
 
         FgsManagerController result = new FgsManagerControllerImpl(
+                mContext,
                 mContext.getResources(),
                 mMainExecutor,
                 mBackgroundExecutor,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/StockTilesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/StockTilesRepositoryTest.kt
index 56cead1..0d2f4ee 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/StockTilesRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/StockTilesRepositoryTest.kt
@@ -17,8 +17,11 @@
 package com.android.systemui.qs.panels.data.repository
 
 import android.content.res.mainResources
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.server.display.feature.flags.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.res.R
@@ -30,12 +33,49 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class StockTilesRepositoryTest : SysuiTestCase() {
-    private val kosmos = testKosmos()
-
-    private val underTest = StockTilesRepository(kosmos.mainResources)
+    private val kosmos =
+        testKosmos().apply { mainResources = mContext.orCreateTestableResources.resources }
 
     @Test
-    fun stockTilesMatchesResources() {
+    @EnableFlags(Flags.FLAG_EVEN_DIMMER)
+    fun stockTilesMatchesResources_evenDimmerFlagOn_configOn() {
+        // Enable the EvenDimmer config
+        mContext
+            .getOrCreateTestableResources()
+            .addOverride(com.android.internal.R.bool.config_evenDimmerEnabled, true)
+        val underTest = StockTilesRepository(kosmos.mainResources)
+
+        val expected =
+            kosmos.mainResources
+                .getString(R.string.quick_settings_tiles_stock)
+                .split(",")
+                .filterNot { it.equals("reduce_brightness") }
+                .map(TileSpec::create)
+        assertThat(underTest.stockTiles).isEqualTo(expected)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_EVEN_DIMMER)
+    fun stockTilesMatchesResources_evenDimmerFlagOn_configOff() {
+        // Disable the EvenDimmer config
+        mContext
+            .getOrCreateTestableResources()
+            .addOverride(com.android.internal.R.bool.config_evenDimmerEnabled, false)
+        val underTest = StockTilesRepository(kosmos.mainResources)
+
+        val expected =
+            kosmos.mainResources
+                .getString(R.string.quick_settings_tiles_stock)
+                .split(",")
+                .map(TileSpec::create)
+        assertThat(underTest.stockTiles).isEqualTo(expected)
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_EVEN_DIMMER)
+    fun stockTilesMatchesResources_evenDimmerFlagOff() {
+        val underTest = StockTilesRepository(kosmos.mainResources)
+
         val expected =
             kosmos.mainResources
                 .getString(R.string.quick_settings_tiles_stock)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt
index ae7c44e..8b9ae9a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt
@@ -39,7 +39,7 @@
 
     @Test
     fun startDrag_listHasSpacers() {
-        underTest.onStarted(TestEditTiles[0])
+        underTest.onStarted(TestEditTiles[0], DragType.Add)
 
         // [ a ] [ b ] [ c ] [ X ]
         // [ Large D ] [ e ] [ X ]
@@ -51,8 +51,8 @@
 
     @Test
     fun moveDrag_listChanges() {
-        underTest.onStarted(TestEditTiles[4])
-        underTest.onMoved(3, false)
+        underTest.onStarted(TestEditTiles[4], DragType.Add)
+        underTest.onTargeting(3, false)
 
         // Tile E goes to index 3
         // [ a ] [ b ] [ c ] [ e ]
@@ -65,8 +65,8 @@
     fun moveDragOnSidesOfLargeTile_listChanges() {
         val draggedCell = TestEditTiles[4]
 
-        underTest.onStarted(draggedCell)
-        underTest.onMoved(4, true)
+        underTest.onStarted(draggedCell, DragType.Add)
+        underTest.onTargeting(4, true)
 
         // Tile E goes to the right side of tile D, list is unchanged
         // [ a ] [ b ] [ c ] [ X ]
@@ -74,7 +74,7 @@
         assertThat(underTest.tiles.toStrings())
             .isEqualTo(listOf("a", "b", "c", "spacer", "d", "e", "spacer"))
 
-        underTest.onMoved(4, false)
+        underTest.onTargeting(4, false)
 
         // Tile E goes to the left side of tile D, they swap positions
         // [ a ] [ b ] [ c ] [ e ]
@@ -87,8 +87,8 @@
     fun moveNewTile_tileIsAdded() {
         val newTile = createEditTile("newTile", 2)
 
-        underTest.onStarted(newTile)
-        underTest.onMoved(5, false)
+        underTest.onStarted(newTile, DragType.Add)
+        underTest.onTargeting(5, false)
 
         // New tile goes to index 5
         // [ a ] [ b ] [ c ] [ X ]
@@ -102,7 +102,7 @@
 
     @Test
     fun movedTileOutOfBounds_tileDisappears() {
-        underTest.onStarted(TestEditTiles[0])
+        underTest.onStarted(TestEditTiles[0], DragType.Add)
         underTest.movedOutOfBounds()
 
         assertThat(underTest.tiles.toStrings()).doesNotContain(TestEditTiles[0].tile.tileSpec.spec)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
index 583db72..bbfa7e7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
@@ -21,6 +21,7 @@
 import android.graphics.drawable.TestStubDrawable
 import android.platform.test.flag.junit.FlagsParameterization
 import androidx.test.filters.SmallTest
+import com.android.internal.logging.uiEventLoggerFake
 import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.ContentDescription
@@ -29,9 +30,12 @@
 import com.android.systemui.common.ui.compose.toAnnotatedString
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.runCurrent
+import com.android.systemui.kosmos.runTest
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.qs.FakeQSFactory
 import com.android.systemui.qs.FakeQSTile
+import com.android.systemui.qs.QSEditEvent
 import com.android.systemui.qs.panels.data.repository.stockTilesRepository
 import com.android.systemui.qs.panels.domain.interactor.FakeTileAvailabilityInteractor
 import com.android.systemui.qs.panels.domain.interactor.tileAvailabilityInteractorsMap
@@ -42,8 +46,10 @@
 import com.android.systemui.qs.pipeline.data.repository.fakeMinimumTilesRepository
 import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
 import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.pipeline.shared.metricSpec
 import com.android.systemui.qs.qsTileFactory
 import com.android.systemui.qs.shared.model.TileCategory
+import com.android.systemui.qs.tiles.impl.airplane.qsAirplaneModeTileConfig
 import com.android.systemui.qs.tiles.impl.alarm.qsAlarmTileConfig
 import com.android.systemui.qs.tiles.impl.battery.qsBatterySaverTileConfig
 import com.android.systemui.qs.tiles.impl.flashlight.qsFlashlightTileConfig
@@ -86,6 +92,7 @@
                 qsFlashlightTileConfig,
                 qsBatterySaverTileConfig,
                 qsAlarmTileConfig,
+                qsAirplaneModeTileConfig,
                 qsCameraSensorPrivacyToggleTileConfig,
                 qsMicrophoneSensorPrivacyToggleTileConfig,
             )
@@ -116,7 +123,7 @@
 
             fakeInstalledTilesRepository.setInstalledServicesForUser(
                 userTracker.userId,
-                listOf(serviceInfo1, serviceInfo2)
+                listOf(serviceInfo1, serviceInfo2),
             )
 
             with(fakeQSTileConfigProvider) { configs.forEach { putConfig(it.tileSpec, it) } }
@@ -424,10 +431,7 @@
             testScope.runTest {
                 val tiles by collectLastValue(underTest.tiles)
                 val currentTiles =
-                    mutableListOf(
-                        TileSpec.create("flashlight"),
-                        TileSpec.create("airplane"),
-                    )
+                    mutableListOf(TileSpec.create("flashlight"), TileSpec.create("airplane"))
                 currentTilesInteractor.setTiles(currentTiles)
                 assertThat(currentTiles.size).isLessThan(minNumberOfTiles)
 
@@ -549,6 +553,156 @@
             }
         }
 
+    // UI EVENT TESTS
+
+    @Test
+    fun startEditing_onlyOneEvent() =
+        kosmos.runTest {
+            underTest.startEditing()
+            underTest.startEditing()
+
+            assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+
+            assertThat(uiEventLoggerFake[0].eventId).isEqualTo(QSEditEvent.QS_EDIT_OPEN.id)
+        }
+
+    @Test
+    fun stopEditing_notEditing_noEvent() =
+        kosmos.runTest {
+            underTest.stopEditing()
+
+            assertThat(uiEventLoggerFake.numLogs()).isEqualTo(0)
+        }
+
+    @Test
+    fun stopEditing_whenEditing_correctEvent() =
+        kosmos.runTest {
+            underTest.startEditing()
+            underTest.stopEditing()
+
+            assertThat(uiEventLoggerFake[1].eventId).isEqualTo(QSEditEvent.QS_EDIT_CLOSED.id)
+        }
+
+    @Test
+    fun addTile_correctPackageAndPosition() =
+        kosmos.runTest {
+            val flashlightTile = TileSpec.create("flashlight")
+            val airplaneTile = TileSpec.create("airplane")
+            val internetTile = TileSpec.create("internet")
+            val customTile = TileSpec.create(component2)
+            currentTilesInteractor.setTiles(listOf(flashlightTile))
+            runCurrent()
+
+            underTest.addTile(airplaneTile)
+            underTest.addTile(internetTile, position = 0)
+            underTest.addTile(customTile, position = 1)
+
+            assertThat(uiEventLoggerFake.numLogs()).isEqualTo(3)
+
+            with(uiEventLoggerFake[0]) {
+                assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_ADD.id)
+                assertThat(packageName).isEqualTo(airplaneTile.metricSpec)
+                assertThat(position).isEqualTo(-1)
+            }
+            with(uiEventLoggerFake[1]) {
+                assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_ADD.id)
+                assertThat(packageName).isEqualTo(internetTile.metricSpec)
+                assertThat(position).isEqualTo(0)
+            }
+            with(uiEventLoggerFake[2]) {
+                assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_ADD.id)
+                assertThat(packageName).isEqualTo(customTile.metricSpec)
+                assertThat(position).isEqualTo(1)
+            }
+        }
+
+    @Test
+    fun addTile_alreadyThere_usesMoveEvent() =
+        kosmos.runTest {
+            val flashlightTile = TileSpec.create("flashlight")
+            val airplaneTile = TileSpec.create("airplane")
+            val internetTile = TileSpec.create("internet")
+            currentTilesInteractor.setTiles(listOf(flashlightTile, airplaneTile, internetTile))
+            runCurrent()
+
+            underTest.addTile(flashlightTile) // adding at the end, should use correct position
+            underTest.addTile(internetTile, 0)
+
+            assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2)
+
+            with(uiEventLoggerFake[0]) {
+                assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_MOVE.id)
+                assertThat(packageName).isEqualTo(flashlightTile.metricSpec)
+                // adding at the end, should use correct position
+                assertThat(position).isEqualTo(2)
+            }
+            with(uiEventLoggerFake[1]) {
+                assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_MOVE.id)
+                assertThat(packageName).isEqualTo(internetTile.metricSpec)
+                assertThat(position).isEqualTo(0)
+            }
+        }
+
+    @Test
+    fun removeTileEvent() =
+        kosmos.runTest {
+            val flashlightTile = TileSpec.create("flashlight")
+            val airplaneTile = TileSpec.create("airplane")
+            val internetTile = TileSpec.create("internet")
+            currentTilesInteractor.setTiles(listOf(flashlightTile, airplaneTile, internetTile))
+            runCurrent()
+
+            underTest.removeTile(airplaneTile)
+
+            assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+
+            with(uiEventLoggerFake[0]) {
+                assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_REMOVE.id)
+                assertThat(packageName).isEqualTo(airplaneTile.metricSpec)
+            }
+        }
+
+    @Test
+    fun setTiles_emitsCorrectOperation_individualOperations() =
+        kosmos.runTest {
+            val flashlightTile = TileSpec.create("flashlight")
+            val airplaneTile = TileSpec.create("airplane")
+            val internetTile = TileSpec.create("internet")
+            val alarmTile = TileSpec.create("alarm")
+
+            currentTilesInteractor.setTiles(listOf(flashlightTile, airplaneTile, internetTile))
+            runCurrent()
+
+            // 0. Move flashlightTile to position 2
+            underTest.setTiles(listOf(airplaneTile, internetTile, flashlightTile))
+            runCurrent()
+
+            // 1. Add alarm tile at position 1
+            underTest.setTiles(listOf(airplaneTile, alarmTile, internetTile, flashlightTile))
+            runCurrent()
+
+            // 2. Remove internetTile
+            underTest.setTiles(listOf(airplaneTile, alarmTile, flashlightTile))
+            runCurrent()
+
+            assertThat(uiEventLoggerFake.numLogs()).isEqualTo(3)
+
+            with(uiEventLoggerFake[0]) {
+                assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_MOVE.id)
+                assertThat(packageName).isEqualTo(flashlightTile.metricSpec)
+                assertThat(position).isEqualTo(2)
+            }
+            with(uiEventLoggerFake[1]) {
+                assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_ADD.id)
+                assertThat(packageName).isEqualTo(alarmTile.metricSpec)
+                assertThat(position).isEqualTo(1)
+            }
+            with(uiEventLoggerFake[2]) {
+                assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_REMOVE.id)
+                assertThat(packageName).isEqualTo(internetTile.metricSpec)
+            }
+        }
+
     companion object {
         private val drawable1 = TestStubDrawable("drawable1")
         private val appName1 = "App1"
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
index 869ab6c..1fc1c0f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
@@ -85,6 +85,24 @@
         assertThat(TileSpec.create("")).isEqualTo(TileSpec.Invalid)
     }
 
+    @Test
+    fun metricSpec_invalid() {
+        assertThat(TileSpec.Invalid.metricSpec).isEmpty()
+    }
+
+    @Test
+    fun metricSpec_platform_specName() {
+        val tile = "spec"
+        assertThat(TileSpec.create(tile).metricSpec).isEqualTo(tile)
+    }
+
+    @Test
+    fun metricSpec_custom_packageName() {
+        val componentName = ComponentName("test_pkg", "test_cls")
+
+        assertThat(TileSpec.create(componentName).metricSpec).isEqualTo(componentName.packageName)
+    }
+
     companion object {
         private const val CUSTOM_TILE_PREFIX = "custom("
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
index 3f4a134..b921ff7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
@@ -18,8 +18,9 @@
 
 import android.net.ConnectivityManager
 import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
 import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.internal.telephony.flags.Flags
@@ -31,6 +32,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
 import com.android.systemui.qs.flags.QsInCompose.isEnabled
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -51,11 +53,17 @@
 import org.mockito.kotlin.any
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
-class AirplaneModeTileTest : SysuiTestCase() {
+class AirplaneModeTileTest(flags: FlagsParameterization) : SysuiTestCase() {
+
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
+    }
 
     @Mock private lateinit var mHost: QSHost
     @Mock private lateinit var mMetricsLogger: MetricsLogger
@@ -149,4 +157,12 @@
             QSTileImpl.ResourceIcon.get(resId)
         }
     }
+
+    companion object {
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+        }
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
index ae00349..cf9ef4d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
@@ -18,9 +18,10 @@
 
 import android.content.Context
 import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
 import android.testing.TestableLooper
 import android.testing.TestableLooper.RunWithLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.systemui.SysuiTestCase
@@ -31,6 +32,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
 import com.android.systemui.qs.flags.QsInCompose.isEnabled
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -51,14 +53,26 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
 @RunWithLooper(setAsMainLooper = true)
 @SmallTest
-class BatterySaverTileTest : SysuiTestCase() {
+class BatterySaverTileTest(flagsParameterization: FlagsParameterization) : SysuiTestCase() {
 
     companion object {
         private const val USER = 10
+
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+        }
+    }
+
+    init {
+        mSetFlagsRule.setFlagsParameterization(flagsParameterization)
     }
 
     @Mock private lateinit var userContext: Context
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt
index 31519c5..6bb6713 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt
@@ -17,10 +17,11 @@
 package com.android.systemui.qs.tiles
 
 import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
 import android.provider.Settings
 import android.safetycenter.SafetyCenterManager
 import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.systemui.SysuiTestCase
@@ -30,6 +31,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLoggerFake
+import com.android.systemui.qs.flags.QSComposeFragment
 import com.android.systemui.qs.flags.QsInCompose.isEnabled
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -45,15 +47,27 @@
 import org.mockito.Mock
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
-class CameraToggleTileTest : SysuiTestCase() {
+class CameraToggleTileTest(flags: FlagsParameterization) : SysuiTestCase() {
     companion object {
         /* isBlocked */
         const val CAMERA_TOGGLE_ENABLED: Boolean = false
         const val CAMERA_TOGGLE_DISABLED: Boolean = true
+
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+        }
+    }
+
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
     }
 
     @Mock private lateinit var host: QSHost
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java
index 2c796a9..a58dd63 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java
@@ -16,6 +16,10 @@
 
 package com.android.systemui.qs.tiles;
 
+import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf;
+
+import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -25,10 +29,10 @@
 
 import android.content.Intent;
 import android.os.Handler;
+import android.platform.test.flag.junit.FlagsParameterization;
 import android.provider.Settings;
 import android.testing.TestableLooper;
 
-import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
@@ -55,13 +59,23 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-@RunWith(AndroidJUnit4.class)
+import java.util.List;
+
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+@RunWith(ParameterizedAndroidJunit4.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
 public class ColorInversionTileTest extends SysuiTestCase {
     private static final Integer COLOR_INVERSION_DISABLED = 0;
     private static final Integer COLOR_INVERSION_ENABLED = 1;
 
+    @Parameters(name = "{0}")
+    public static List<FlagsParameterization> getParams() {
+        return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX);
+    }
+
     @Mock
     private QSHost mHost;
     @Mock
@@ -81,6 +95,11 @@
     private SecureSettings mSecureSettings;
     private ColorInversionTile mTile;
 
+    public ColorInversionTileTest(FlagsParameterization flags) {
+        super();
+        mSetFlagsRule.setFlagsParameterization(flags);
+    }
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt
index 23be9da..fbbdc46 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt
@@ -17,8 +17,9 @@
 package com.android.systemui.qs.tiles
 
 import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
 import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.systemui.SysuiTestCase
@@ -29,6 +30,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
 import com.android.systemui.qs.flags.QsInCompose.isEnabled
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -44,11 +46,18 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.eq
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
-class DataSaverTileTest : SysuiTestCase() {
+class DataSaverTileTest(flags: FlagsParameterization) : SysuiTestCase() {
+
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
+    }
 
     @Mock private lateinit var mHost: QSHost
     @Mock private lateinit var mMetricsLogger: MetricsLogger
@@ -71,7 +80,7 @@
         testableLooper = TestableLooper.get(this)
 
         whenever(mHost.context).thenReturn(mContext)
-        whenever(systemUIDialogFactory.create()).thenReturn(systemUIDialog)
+        whenever(systemUIDialogFactory.create(eq(mContext))).thenReturn(systemUIDialog)
 
         tile =
             DataSaverTile(
@@ -121,4 +130,12 @@
             QSTileImpl.ResourceIcon.get(resId)
         }
     }
+
+    companion object {
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+        }
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
index 33748b9..0bb86da 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
@@ -20,11 +20,14 @@
 import android.content.Context
 import android.content.Intent
 import android.os.Handler
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
 import android.provider.Settings
 import android.service.quicksettings.Tile
 import android.testing.TestableLooper
 import androidx.lifecycle.LifecycleOwner
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.systemui.SysuiTestCase
@@ -43,7 +46,9 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
 import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.res.R
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.capture
@@ -67,11 +72,17 @@
 import org.mockito.Mockito.verifyNoMoreInteractions
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
 @SmallTest
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-class DeviceControlsTileTest : SysuiTestCase() {
+class DeviceControlsTileTest(flags: FlagsParameterization) : SysuiTestCase() {
+
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
+    }
 
     @Mock private lateinit var qsHost: QSHost
     @Mock private lateinit var metricsLogger: MetricsLogger
@@ -130,7 +141,7 @@
             if (featureEnabled) {
                 Optional.of(controlsController)
             } else {
-                Optional.empty()
+                Optional.empty<ControlsController>()
             }
         }
 
@@ -138,7 +149,7 @@
             if (featureEnabled) {
                 Optional.of(controlsListingController)
             } else {
-                Optional.empty()
+                Optional.empty<ControlsController>()
             }
         }
 
@@ -146,12 +157,12 @@
             if (featureEnabled) {
                 Optional.of(controlsUiController)
             } else {
-                Optional.empty()
+                Optional.empty<ControlsController>()
             }
         }
 
         `when`(controlsComponent.getTileTitleId()).thenReturn(R.string.quick_controls_title)
-        `when`(controlsComponent.getTileTitleId()).thenReturn(R.drawable.controls_icon)
+        `when`(controlsComponent.getTileImageId()).thenReturn(R.drawable.controls_icon)
     }
 
     @Test
@@ -378,6 +389,28 @@
         assertThat(tile.tileLabel).isEqualTo(context.getText(controlsComponent.getTileTitleId()))
     }
 
+    @Test
+    @DisableFlags(QSComposeFragment.FLAG_NAME)
+    fun tileIconEqualsResourceFromComponent_composeFlagDisabled() {
+        tile.refreshState()
+        testableLooper.processAllMessages()
+        assertThat(tile.state.icon).isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.controls_icon))
+    }
+
+    @Test
+    @EnableFlags(QSComposeFragment.FLAG_NAME)
+    fun tileIconEqualsResourceFromComponent_composeFlagEnable() {
+        tile.refreshState()
+        testableLooper.processAllMessages()
+        assertThat(tile.state.icon)
+            .isEqualTo(
+                QSTileImpl.DrawableIconWithRes(
+                    mContext.getDrawable(R.drawable.controls_icon),
+                    R.drawable.controls_icon,
+                )
+            )
+    }
+
     private fun createTile(): DeviceControlsTile {
         return DeviceControlsTile(
                 qsHost,
@@ -396,6 +429,14 @@
                 testableLooper.processAllMessages()
             }
     }
+
+    companion object {
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+        }
+    }
 }
 
 private const val CONTROLS_ACTIVITY_CLASS_NAME = "com.android.systemui.controls.ui.ControlsActivity"
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt
index 3cb9091..6a15a5b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt
@@ -1,9 +1,9 @@
 package com.android.systemui.qs.tiles
 
-import android.content.Context
 import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
 import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.systemui.SysuiTestCase
@@ -13,6 +13,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
 import com.android.systemui.qs.flags.QsInCompose.isEnabled
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -27,13 +28,17 @@
 import org.mockito.Mock
 import org.mockito.Mockito
 import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
-class FlashlightTileTest : SysuiTestCase() {
+class FlashlightTileTest(flags: FlagsParameterization) : SysuiTestCase() {
 
-    @Mock private lateinit var mockContext: Context
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
+    }
 
     @Mock private lateinit var qsLogger: QSLogger
 
@@ -58,7 +63,7 @@
         MockitoAnnotations.initMocks(this)
         testableLooper = TestableLooper.get(this)
 
-        Mockito.`when`(qsHost.context).thenReturn(mockContext)
+        Mockito.`when`(qsHost.context).thenReturn(mContext)
 
         tile =
             FlashlightTile(
@@ -122,4 +127,12 @@
             QSTileImpl.ResourceIcon.get(resId)
         }
     }
+
+    companion object {
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+        }
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
index f33de4d..eeccbdf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
@@ -17,10 +17,11 @@
 package com.android.systemui.qs.tiles
 
 import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
 import android.service.quicksettings.Tile
 import android.testing.TestableLooper
 import android.testing.TestableLooper.RunWithLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.systemui.SysuiTestCase
@@ -29,6 +30,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tiles.dialog.InternetDialogManager
 import com.android.systemui.qs.tiles.dialog.WifiStateWorker
@@ -62,12 +64,18 @@
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWithLooper(setAsMainLooper = true)
-@RunWith(AndroidJUnit4::class)
-class InternetTileNewImplTest : SysuiTestCase() {
+@RunWith(ParameterizedAndroidJunit4::class)
+class InternetTileNewImplTest(flags: FlagsParameterization) : SysuiTestCase() {
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
+    }
+
     lateinit var underTest: InternetTileNewImpl
 
     private val testDispatcher = StandardTestDispatcher()
@@ -252,5 +260,11 @@
         const val WIFI_SSID = "test ssid"
         val ACTIVE_WIFI =
             WifiNetworkModel.Active.of(isValidated = true, level = 4, ssid = WIFI_SSID)
+
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+        }
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileTest.java
index b5a64b3..d7b183e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileTest.java
@@ -16,6 +16,10 @@
 
 package com.android.systemui.qs.tiles;
 
+import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf;
+
+import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.eq;
@@ -25,10 +29,10 @@
 import static org.mockito.Mockito.when;
 
 import android.os.Handler;
+import android.platform.test.flag.junit.FlagsParameterization;
 import android.service.quicksettings.Tile;
 import android.testing.TestableLooper;
 
-import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
@@ -57,11 +61,21 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-@RunWith(AndroidJUnit4.class)
+import java.util.List;
+
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+@RunWith(ParameterizedAndroidJunit4.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
 public class InternetTileTest extends SysuiTestCase {
 
+    @Parameters(name = "{0}")
+    public static List<FlagsParameterization> getParams() {
+        return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX);
+    }
+
     @Mock
     private QSHost mHost;
     @Mock
@@ -78,6 +92,11 @@
     private TestableLooper mTestableLooper;
     private InternetTile mTile;
 
+    public InternetTileTest(FlagsParameterization flags) {
+        super();
+        mSetFlagsRule.setFlagsParameterization(flags);
+    }
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/LocationTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
index 4be1899..a581b57 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
@@ -16,10 +16,10 @@
 
 package com.android.systemui.qs.tiles
 
-import android.content.Context
 import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
 import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.systemui.SysuiTestCase
@@ -29,6 +29,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
 import com.android.systemui.qs.flags.QsInCompose.isEnabled
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
@@ -48,13 +49,18 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
-class LocationTileTest : SysuiTestCase() {
+class LocationTileTest(flags: FlagsParameterization) : SysuiTestCase() {
 
-    @Mock private lateinit var mockContext: Context
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
+    }
+
     @Mock private lateinit var qsLogger: QSLogger
     @Mock private lateinit var qsHost: QSHost
     @Mock private lateinit var metricsLogger: MetricsLogger
@@ -73,7 +79,7 @@
     fun setUp() {
         MockitoAnnotations.initMocks(this)
         testableLooper = TestableLooper.get(this)
-        `when`(qsHost.context).thenReturn(mockContext)
+        `when`(qsHost.context).thenReturn(mContext)
 
         tile =
             LocationTile(
@@ -139,4 +145,12 @@
             QSTileImpl.ResourceIcon.get(resId)
         }
     }
+
+    companion object {
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+        }
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
index afe9713..a39692d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
@@ -17,10 +17,11 @@
 package com.android.systemui.qs.tiles
 
 import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
 import android.provider.Settings
 import android.safetycenter.SafetyCenterManager
 import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.systemui.SysuiTestCase
@@ -30,6 +31,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
 import com.android.systemui.qs.flags.QsInCompose.isEnabled
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -45,15 +47,27 @@
 import org.mockito.Mock
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
-class MicrophoneToggleTileTest : SysuiTestCase() {
+class MicrophoneToggleTileTest(flags: FlagsParameterization) : SysuiTestCase() {
     companion object {
         /* isBlocked */
         const val MICROPHONE_TOGGLE_ENABLED: Boolean = false
         const val MICROPHONE_TOGGLE_DISABLED: Boolean = true
+
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+        }
+    }
+
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
     }
 
     @Mock private lateinit var host: QSHost
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt
index 69dab39..a193cbc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt
@@ -19,8 +19,9 @@
 import android.hardware.display.ColorDisplayManager
 import android.hardware.display.NightDisplayListener
 import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
 import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.systemui.SysuiTestCase
@@ -31,6 +32,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
 import com.android.systemui.qs.flags.QsInCompose.isEnabled
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -46,11 +48,18 @@
 import org.mockito.Mockito.anyInt
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
-class NightDisplayTileTest : SysuiTestCase() {
+class NightDisplayTileTest(flags: FlagsParameterization) : SysuiTestCase() {
+
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
+    }
+
     @Mock private lateinit var mHost: QSHost
 
     @Mock private lateinit var mMetricsLogger: MetricsLogger
@@ -135,4 +144,12 @@
             QSTileImpl.ResourceIcon.get(resId)
         }
     }
+
+    companion object {
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+        }
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
index 2345128..c244984 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
@@ -16,6 +16,10 @@
 
 package com.android.systemui.qs.tiles;
 
+import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf;
+
+import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX;
+
 import static junit.framework.Assert.assertEquals;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -28,10 +32,10 @@
 import android.os.Handler;
 import android.platform.test.annotations.RequiresFlagsDisabled;
 import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.FlagsParameterization;
 import android.service.quicksettings.Tile;
 import android.testing.TestableLooper;
 
-import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.R;
@@ -59,10 +63,21 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-@RunWith(AndroidJUnit4.class)
+import java.util.List;
+
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+@RunWith(ParameterizedAndroidJunit4.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
 public class ReduceBrightColorsTileTest extends SysuiTestCase {
+
+    @Parameters(name = "{0}")
+    public static List<FlagsParameterization> getParams() {
+        return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX);
+    }
+
     @Mock
     private QSHost mHost;
     @Mock
@@ -85,6 +100,11 @@
     private TestableLooper mTestableLooper;
     private ReduceBrightColorsTile mTile;
 
+    public ReduceBrightColorsTileTest(FlagsParameterization flags) {
+        super();
+        mSetFlagsRule.setFlagsParameterization(flags);
+    }
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
index 7fb0eab..fee358a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
@@ -17,6 +17,9 @@
 package com.android.systemui.qs.tiles;
 
 import static android.hardware.SensorPrivacyManager.Sensors.CAMERA;
+import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf;
+
+import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX;
 
 import static junit.framework.TestCase.assertEquals;
 
@@ -27,10 +30,10 @@
 import android.content.pm.PackageManager;
 import android.hardware.SensorPrivacyManager;
 import android.os.Handler;
+import android.platform.test.flag.junit.FlagsParameterization;
 import android.testing.TestableLooper;
 import android.testing.TestableResources;
 
-import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
@@ -59,7 +62,12 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-@RunWith(AndroidJUnit4.class)
+import java.util.List;
+
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+@RunWith(ParameterizedAndroidJunit4.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
 public class RotationLockTileTest extends SysuiTestCase {
@@ -70,6 +78,11 @@
             "1:2"
     };
 
+    @Parameters(name = "{0}")
+    public static List<FlagsParameterization> getParams() {
+        return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX);
+    }
+
     @Mock
     private PackageManager mPackageManager;
     @Mock
@@ -98,6 +111,11 @@
     private RotationLockTile mLockTile;
     private TestableResources mTestableResources;
 
+    public RotationLockTileTest(FlagsParameterization flags) {
+        super();
+        mSetFlagsRule.setFlagsParameterization(flags);
+    }
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
index a7c7a78..fc1d73b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
@@ -16,6 +16,10 @@
 
 package com.android.systemui.qs.tiles;
 
+import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf;
+
+import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertTrue;
@@ -31,10 +35,10 @@
 import android.app.Dialog;
 import android.media.projection.StopReason;
 import android.os.Handler;
+import android.platform.test.flag.junit.FlagsParameterization;
 import android.service.quicksettings.Tile;
 import android.testing.TestableLooper;
 
-import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
@@ -66,11 +70,21 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-@RunWith(AndroidJUnit4.class)
+import java.util.List;
+
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+@RunWith(ParameterizedAndroidJunit4.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
 public class ScreenRecordTileTest extends SysuiTestCase {
 
+    @Parameters(name = "{0}")
+    public static List<FlagsParameterization> getParams() {
+        return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX);
+    }
+
     @Mock
     private RecordingController mController;
     @Mock
@@ -105,6 +119,11 @@
     private TestableLooper mTestableLooper;
     private ScreenRecordTile mTile;
 
+    public ScreenRecordTileTest(FlagsParameterization flags) {
+        super();
+        mSetFlagsRule.setFlagsParameterization(flags);
+    }
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt
index 773e225..3246e64 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt
@@ -17,12 +17,11 @@
 package com.android.systemui.qs.tiles
 
 import android.app.UiModeManager
-import android.content.Context
 import android.content.res.Configuration
-import android.content.res.Resources
 import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
 import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.systemui.SysuiTestCase
@@ -32,6 +31,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
 import com.android.systemui.qs.flags.QsInCompose.isEnabled
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -48,15 +48,19 @@
 import org.mockito.Mock
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
-class UiModeNightTileTest : SysuiTestCase() {
+class UiModeNightTileTest(flags: FlagsParameterization) : SysuiTestCase() {
 
-    @Mock private lateinit var mockContext: Context
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
+    }
+
     @Mock private lateinit var uiModeManager: UiModeManager
-    @Mock private lateinit var resources: Resources
     @Mock private lateinit var qsLogger: QSLogger
     @Mock private lateinit var qsHost: QSHost
     @Mock private lateinit var metricsLogger: MetricsLogger
@@ -70,19 +74,19 @@
     private val falsingManager = FalsingManagerFake()
     private lateinit var testableLooper: TestableLooper
     private lateinit var tile: UiModeNightTile
-    private lateinit var configuration: Configuration
+    private val configuration = Configuration()
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
+        val initialConfiguration = mContext.resources.configuration
+        onTeardown { mContext.resources.configuration.updateFrom(initialConfiguration) }
+
         testableLooper = TestableLooper.get(this)
-        configuration = Configuration()
         mContext.addMockSystemService(UiModeManager::class.java, uiModeManager)
 
-        `when`(qsHost.context).thenReturn(mockContext)
+        `when`(qsHost.context).thenReturn(mContext)
         `when`(qsHost.userContext).thenReturn(mContext)
-        `when`(mockContext.resources).thenReturn(resources)
-        `when`(resources.configuration).thenReturn(configuration)
 
         tile =
             UiModeNightTile(
@@ -118,7 +122,7 @@
     }
 
     @Test
-    fun testIcon_whenNightModeOn_isOffState() {
+    fun testIcon_whenNightModeOff_isOffState() {
         val state = QSTile.BooleanState()
         setNightModeOff()
 
@@ -131,11 +135,13 @@
     private fun setNightModeOn() {
         `when`(uiModeManager.nightMode).thenReturn(UiModeManager.MODE_NIGHT_YES)
         configuration.uiMode = Configuration.UI_MODE_NIGHT_YES
+        mContext.resources.configuration.updateFrom(configuration)
     }
 
     private fun setNightModeOff() {
         `when`(uiModeManager.nightMode).thenReturn(UiModeManager.MODE_NIGHT_NO)
         configuration.uiMode = Configuration.UI_MODE_NIGHT_NO
+        mContext.resources.configuration.updateFrom(configuration)
     }
 
     private fun createExpectedIcon(resId: Int): QSTile.Icon {
@@ -145,4 +151,12 @@
             QSTileImpl.ResourceIcon.get(resId)
         }
     }
+
+    companion object {
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+        }
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/user/UserSwitchDialogControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/user/UserSwitchDialogControllerTest.kt
index ad6c64b..039a1dc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/user/UserSwitchDialogControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/user/UserSwitchDialogControllerTest.kt
@@ -32,7 +32,6 @@
 import com.android.systemui.qs.QSUserSwitcherEvent
 import com.android.systemui.qs.tiles.UserDetailView
 import com.android.systemui.statusbar.phone.SystemUIDialog
-import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
@@ -51,31 +50,22 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class UserSwitchDialogControllerTest : SysuiTestCase() {
 
-    @Mock
-    private lateinit var dialogFactory: SystemUIDialog.Factory
-    @Mock
-    private lateinit var dialog: SystemUIDialog
-    @Mock
-    private lateinit var falsingManager: FalsingManager
-    @Mock
-    private lateinit var activityStarter: ActivityStarter
-    @Mock
-    private lateinit var userDetailViewAdapter: UserDetailView.Adapter
-    @Mock
-    private lateinit var launchExpandable: Expandable
-    @Mock
-    private lateinit var neutralButton: Button
-    @Mock
-    private lateinit var mDialogTransitionAnimator: DialogTransitionAnimator
-    @Mock
-    private lateinit var uiEventLogger: UiEventLogger
-    @Captor
-    private lateinit var clickCaptor: ArgumentCaptor<DialogInterface.OnClickListener>
+    @Mock private lateinit var dialogFactory: SystemUIDialog.Factory
+    @Mock private lateinit var dialog: SystemUIDialog
+    @Mock private lateinit var falsingManager: FalsingManager
+    @Mock private lateinit var activityStarter: ActivityStarter
+    @Mock private lateinit var userDetailViewAdapter: UserDetailView.Adapter
+    @Mock private lateinit var launchExpandable: Expandable
+    @Mock private lateinit var neutralButton: Button
+    @Mock private lateinit var mDialogTransitionAnimator: DialogTransitionAnimator
+    @Mock private lateinit var uiEventLogger: UiEventLogger
+    @Captor private lateinit var clickCaptor: ArgumentCaptor<DialogInterface.OnClickListener>
 
     private lateinit var controller: UserSwitchDialogController
 
@@ -84,16 +74,17 @@
         MockitoAnnotations.initMocks(this)
 
         whenever(dialog.context).thenReturn(mContext)
-        whenever(dialogFactory.create()).thenReturn(dialog)
+        whenever(dialogFactory.create(eq(mContext))).thenReturn(dialog)
 
-        controller = UserSwitchDialogController(
-            { userDetailViewAdapter },
-            activityStarter,
-            falsingManager,
-            mDialogTransitionAnimator,
-            uiEventLogger,
-            dialogFactory
-        )
+        controller =
+            UserSwitchDialogController(
+                { userDetailViewAdapter },
+                activityStarter,
+                falsingManager,
+                mDialogTransitionAnimator,
+                uiEventLogger,
+                dialogFactory,
+            )
     }
 
     @Test
@@ -150,7 +141,7 @@
             .postStartActivityDismissingKeyguard(
                 argThat(IntentMatcher(Settings.ACTION_USER_SETTINGS)),
                 eq(0),
-                eq(null)
+                eq(null),
             )
         verify(uiEventLogger).log(QSUserSwitcherEvent.QS_USER_MORE_SETTINGS)
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicyTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicyTest.kt
index ef1ae09..fd9f5f0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicyTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicyTest.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.display.data.repository.display
 import com.android.systemui.display.data.repository.displayRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.kosmos.useUnconfinedTestDispatcher
 import com.android.systemui.testKosmos
@@ -38,17 +39,31 @@
 class StatusBarTouchShadeDisplayPolicyTest : SysuiTestCase() {
     private val kosmos = testKosmos().useUnconfinedTestDispatcher()
     private val testScope = kosmos.testScope
+    private val keyguardRepository = kosmos.fakeKeyguardRepository
     private val displayRepository = kosmos.displayRepository
-    val underTest = StatusBarTouchShadeDisplayPolicy(displayRepository, testScope.backgroundScope)
+
+    private fun createUnderTest(
+        shadeOnDefaultDisplayWhenLocked: Boolean = false
+    ): StatusBarTouchShadeDisplayPolicy {
+        return StatusBarTouchShadeDisplayPolicy(
+            displayRepository,
+            keyguardRepository,
+            testScope.backgroundScope,
+            shadeOnDefaultDisplayWhenLocked = shadeOnDefaultDisplayWhenLocked,
+        )
+    }
 
     @Test
     fun displayId_defaultToDefaultDisplay() {
+        val underTest = createUnderTest()
+
         assertThat(underTest.displayId.value).isEqualTo(Display.DEFAULT_DISPLAY)
     }
 
     @Test
     fun onStatusBarTouched_called_updatesDisplayId() =
         testScope.runTest {
+            val underTest = createUnderTest()
             val displayId by collectLastValue(underTest.displayId)
 
             displayRepository.addDisplays(display(id = 2, type = TYPE_EXTERNAL))
@@ -60,6 +75,7 @@
     @Test
     fun onStatusBarTouched_notExistentDisplay_displayIdNotUpdated() =
         testScope.runTest {
+            val underTest = createUnderTest()
             val displayIds by collectValues(underTest.displayId)
             assertThat(displayIds).isEqualTo(listOf(Display.DEFAULT_DISPLAY))
 
@@ -72,6 +88,7 @@
     @Test
     fun onStatusBarTouched_afterDisplayRemoved_goesBackToDefaultDisplay() =
         testScope.runTest {
+            val underTest = createUnderTest()
             val displayId by collectLastValue(underTest.displayId)
 
             displayRepository.addDisplays(display(id = 2, type = TYPE_EXTERNAL))
@@ -83,4 +100,40 @@
 
             assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY)
         }
+
+    @Test
+    fun onStatusBarTouched_afterKeyguardVisible_goesBackToDefaultDisplay() =
+        testScope.runTest {
+            val underTest = createUnderTest(shadeOnDefaultDisplayWhenLocked = true)
+            val displayId by collectLastValue(underTest.displayId)
+
+            displayRepository.addDisplays(display(id = 2, type = TYPE_EXTERNAL))
+            underTest.onStatusBarTouched(2)
+
+            assertThat(displayId).isEqualTo(2)
+
+            keyguardRepository.setKeyguardShowing(true)
+
+            assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY)
+        }
+
+    @Test
+    fun onStatusBarTouched_afterKeyguardHides_goesBackToPreviousDisplay() =
+        testScope.runTest {
+            val underTest = createUnderTest(shadeOnDefaultDisplayWhenLocked = true)
+            val displayId by collectLastValue(underTest.displayId)
+
+            displayRepository.addDisplays(display(id = 2, type = TYPE_EXTERNAL))
+            underTest.onStatusBarTouched(2)
+
+            assertThat(displayId).isEqualTo(2)
+
+            keyguardRepository.setKeyguardShowing(true)
+
+            assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY)
+
+            keyguardRepository.setKeyguardShowing(false)
+
+            assertThat(displayId).isEqualTo(2)
+        }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
index a8d5c31..e93d0ef 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
@@ -16,32 +16,26 @@
 
 package com.android.systemui.shade.domain.interactor
 
-import android.content.mockedContext
 import android.content.res.Configuration
 import android.content.res.mockResources
 import android.view.Display
-import android.view.mockWindowManager
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.kosmos.testScope
 import com.android.systemui.kosmos.useUnconfinedTestDispatcher
 import com.android.systemui.scene.ui.view.mockShadeRootView
 import com.android.systemui.shade.data.repository.fakeShadeDisplaysRepository
 import com.android.systemui.testKosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.advanceUntilIdle
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.Mockito.inOrder
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
 import org.mockito.kotlin.any
 import org.mockito.kotlin.eq
 import org.mockito.kotlin.mock
-import org.mockito.kotlin.verifyNoMoreInteractions
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class ShadeDisplaysInteractorTest : SysuiTestCase() {
@@ -49,9 +43,7 @@
 
     private val shadeRootview = kosmos.mockShadeRootView
     private val positionRepository = kosmos.fakeShadeDisplaysRepository
-    private val shadeContext = kosmos.mockedContext
-    private val testScope = kosmos.testScope
-    private val shadeWm = kosmos.mockWindowManager
+    private val shadeContext = kosmos.mockedWindowContext
     private val resources = kosmos.mockResources
     private val configuration = mock<Configuration>()
     private val display = mock<Display>()
@@ -66,8 +58,8 @@
         whenever(resources.configuration).thenReturn(configuration)
 
         whenever(shadeContext.displayId).thenReturn(0)
-        whenever(shadeContext.getSystemService(any())).thenReturn(shadeWm)
         whenever(shadeContext.resources).thenReturn(resources)
+        whenever(shadeContext.display).thenReturn(display)
     }
 
     @Test
@@ -77,7 +69,7 @@
 
         underTest.start()
 
-        verifyNoMoreInteractions(shadeWm)
+        verify(shadeContext, never()).reparentToDisplay(any())
     }
 
     @Test
@@ -87,24 +79,6 @@
 
         underTest.start()
 
-        inOrder(shadeWm).apply {
-            verify(shadeWm).removeView(eq(shadeRootview))
-            verify(shadeWm).addView(eq(shadeRootview), any())
-        }
-    }
-
-    @Test
-    fun start_shadePositionChanges_removedThenAdded() {
-        whenever(display.displayId).thenReturn(0)
-        positionRepository.setDisplayId(0)
-        underTest.start()
-
-        positionRepository.setDisplayId(1)
-        testScope.advanceUntilIdle()
-
-        inOrder(shadeWm).apply {
-            verify(shadeWm).removeView(eq(shadeRootview))
-            verify(shadeWm).addView(eq(shadeRootview), any())
-        }
+        verify(shadeContext).reparentToDisplay(eq(1))
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/CommunalSmartspaceControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/CommunalSmartspaceControllerTest.kt
index 7842d75..f9b4488 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/CommunalSmartspaceControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/CommunalSmartspaceControllerTest.kt
@@ -111,6 +111,8 @@
         override fun getCurrentCardTopPadding(): Int {
             return 0
         }
+
+        override fun setHorizontalPaddings(horizontalPadding: Int) {}
     }
 
     @Before
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
index c83c82d..70ba00e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
@@ -127,6 +127,8 @@
         override fun getCurrentCardTopPadding(): Int {
             return 0
         }
+
+        override fun setHorizontalPaddings(horizontalPadding: Int) {}
     }
 
     @Before
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt
index 611318a..dea3d1f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt
@@ -197,7 +197,7 @@
                         if (
                             (it.arguments[0] as Intent).`package` == CAST_TO_OTHER_DEVICES_PACKAGE
                         ) {
-                            emptyList()
+                            emptyList<ResolveInfo>()
                         } else {
                             listOf(mock<ResolveInfo>())
                         }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorTest.kt
index f06bab7..63efc55 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorTest.kt
@@ -29,6 +29,7 @@
 import com.android.systemui.statusbar.chips.notification.domain.model.NotificationChipModel
 import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
 import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
@@ -46,7 +47,12 @@
         kosmos.runTest {
             val icon = mock<StatusBarIconView>()
             val startingNotif =
-                activeNotificationModel(key = "notif1", statusBarChipIcon = icon, whenTime = 5432)
+                activeNotificationModel(
+                    key = "notif1",
+                    statusBarChipIcon = icon,
+                    whenTime = 5432,
+                    promotedContent = PROMOTED_CONTENT,
+                )
 
             val underTest = factory.create(startingNotif)
 
@@ -63,7 +69,11 @@
             val originalIconView = mock<StatusBarIconView>()
             val underTest =
                 factory.create(
-                    activeNotificationModel(key = "notif1", statusBarChipIcon = originalIconView)
+                    activeNotificationModel(
+                        key = "notif1",
+                        statusBarChipIcon = originalIconView,
+                        promotedContent = PROMOTED_CONTENT,
+                    )
                 )
 
             val latest by collectLastValue(underTest.notificationChip)
@@ -74,6 +84,7 @@
                     key = "notif1",
                     statusBarChipIcon = newIconView,
                     whenTime = 6543,
+                    promotedContent = PROMOTED_CONTENT,
                 )
             )
 
@@ -88,14 +99,22 @@
             val originalIconView = mock<StatusBarIconView>()
             val underTest =
                 factory.create(
-                    activeNotificationModel(key = "notif1", statusBarChipIcon = originalIconView)
+                    activeNotificationModel(
+                        key = "notif1",
+                        statusBarChipIcon = originalIconView,
+                        promotedContent = PROMOTED_CONTENT,
+                    )
                 )
 
             val latest by collectLastValue(underTest.notificationChip)
 
             val newIconView = mock<StatusBarIconView>()
             underTest.setNotification(
-                activeNotificationModel(key = "other_notif", statusBarChipIcon = newIconView)
+                activeNotificationModel(
+                    key = "other_notif",
+                    statusBarChipIcon = newIconView,
+                    promotedContent = PROMOTED_CONTENT,
+                )
             )
 
             assertThat(latest!!.key).isEqualTo("notif1")
@@ -103,10 +122,43 @@
         }
 
     @Test
+    fun notificationChip_ignoresSetWithNullPromotedContent() =
+        kosmos.runTest {
+            val originalIconView = mock<StatusBarIconView>()
+            val underTest =
+                factory.create(
+                    activeNotificationModel(
+                        key = "notif1",
+                        statusBarChipIcon = originalIconView,
+                        promotedContent = PROMOTED_CONTENT,
+                    )
+                )
+
+            val latest by collectLastValue(underTest.notificationChip)
+
+            val newIconView = mock<StatusBarIconView>()
+            underTest.setNotification(
+                activeNotificationModel(
+                    key = "notif1",
+                    statusBarChipIcon = newIconView,
+                    promotedContent = null,
+                )
+            )
+
+            assertThat(latest!!.statusBarChipIconView).isEqualTo(originalIconView)
+        }
+
+    @Test
     fun notificationChip_missingStatusBarIconChipView_inConstructor_emitsNull() =
         kosmos.runTest {
             val underTest =
-                factory.create(activeNotificationModel(key = "notif1", statusBarChipIcon = null))
+                factory.create(
+                    activeNotificationModel(
+                        key = "notif1",
+                        statusBarChipIcon = null,
+                        promotedContent = PROMOTED_CONTENT,
+                    )
+                )
 
             val latest by collectLastValue(underTest.notificationChip)
 
@@ -123,6 +175,7 @@
                         key = "notif1",
                         statusBarChipIcon = null,
                         whenTime = 123L,
+                        promotedContent = PROMOTED_CONTENT,
                     )
                 )
 
@@ -130,20 +183,34 @@
 
             assertThat(latest)
                 .isEqualTo(
-                    NotificationChipModel("notif1", statusBarChipIconView = null, whenTime = 123L)
+                    NotificationChipModel(
+                        "notif1",
+                        statusBarChipIconView = null,
+                        whenTime = 123L,
+                        promotedContent = PROMOTED_CONTENT,
+                    )
                 )
         }
 
     @Test
     fun notificationChip_missingStatusBarIconChipView_inSet_emitsNull() =
         kosmos.runTest {
-            val startingNotif = activeNotificationModel(key = "notif1", statusBarChipIcon = mock())
+            val startingNotif =
+                activeNotificationModel(
+                    key = "notif1",
+                    statusBarChipIcon = mock(),
+                    promotedContent = PROMOTED_CONTENT,
+                )
             val underTest = factory.create(startingNotif)
             val latest by collectLastValue(underTest.notificationChip)
             assertThat(latest).isNotNull()
 
             underTest.setNotification(
-                activeNotificationModel(key = "notif1", statusBarChipIcon = null)
+                activeNotificationModel(
+                    key = "notif1",
+                    statusBarChipIcon = null,
+                    promotedContent = PROMOTED_CONTENT,
+                )
             )
 
             assertThat(latest).isNull()
@@ -153,13 +220,23 @@
     @EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
     fun notificationChip_missingStatusBarIconChipView_inSet_cdEnabled_emitsNotNull() =
         kosmos.runTest {
-            val startingNotif = activeNotificationModel(key = "notif1", statusBarChipIcon = mock())
+            val startingNotif =
+                activeNotificationModel(
+                    key = "notif1",
+                    statusBarChipIcon = mock(),
+                    promotedContent = PROMOTED_CONTENT,
+                )
             val underTest = factory.create(startingNotif)
             val latest by collectLastValue(underTest.notificationChip)
             assertThat(latest).isNotNull()
 
             underTest.setNotification(
-                activeNotificationModel(key = "notif1", statusBarChipIcon = null, whenTime = 123L)
+                activeNotificationModel(
+                    key = "notif1",
+                    statusBarChipIcon = null,
+                    whenTime = 123L,
+                    promotedContent = PROMOTED_CONTENT,
+                )
             )
 
             assertThat(latest)
@@ -168,18 +245,41 @@
                         key = "notif1",
                         statusBarChipIconView = null,
                         whenTime = 123L,
+                        promotedContent = PROMOTED_CONTENT,
                     )
                 )
         }
 
     @Test
+    fun notificationChip_missingPromotedContent_inConstructor_emitsNull() =
+        kosmos.runTest {
+            val underTest =
+                factory.create(
+                    activeNotificationModel(
+                        key = "notif1",
+                        statusBarChipIcon = mock(),
+                        promotedContent = null,
+                    )
+                )
+
+            val latest by collectLastValue(underTest.notificationChip)
+
+            assertThat(latest).isNull()
+        }
+
+    @Test
     fun notificationChip_appIsVisibleOnCreation_emitsNull() =
         kosmos.runTest {
             activityManagerRepository.fake.startingIsAppVisibleValue = true
 
             val underTest =
                 factory.create(
-                    activeNotificationModel(key = "notif", uid = UID, statusBarChipIcon = mock())
+                    activeNotificationModel(
+                        key = "notif",
+                        uid = UID,
+                        statusBarChipIcon = mock(),
+                        promotedContent = PROMOTED_CONTENT,
+                    )
                 )
 
             val latest by collectLastValue(underTest.notificationChip)
@@ -194,7 +294,12 @@
 
             val underTest =
                 factory.create(
-                    activeNotificationModel(key = "notif", uid = UID, statusBarChipIcon = mock())
+                    activeNotificationModel(
+                        key = "notif",
+                        uid = UID,
+                        statusBarChipIcon = mock(),
+                        promotedContent = PROMOTED_CONTENT,
+                    )
                 )
 
             val latest by collectLastValue(underTest.notificationChip)
@@ -207,7 +312,12 @@
         kosmos.runTest {
             val underTest =
                 factory.create(
-                    activeNotificationModel(key = "notif", uid = UID, statusBarChipIcon = mock())
+                    activeNotificationModel(
+                        key = "notif",
+                        uid = UID,
+                        statusBarChipIcon = mock(),
+                        promotedContent = PROMOTED_CONTENT,
+                    )
                 )
 
             val latest by collectLastValue(underTest.notificationChip)
@@ -239,6 +349,7 @@
                         key = "notif",
                         uid = hiddenUid,
                         statusBarChipIcon = mock(),
+                        promotedContent = PROMOTED_CONTENT,
                     )
                 )
             val latest by collectLastValue(underTest.notificationChip)
@@ -247,7 +358,12 @@
             // WHEN the notif gets a new UID that starts as visible
             activityManagerRepository.fake.startingIsAppVisibleValue = true
             underTest.setNotification(
-                activeNotificationModel(key = "notif", uid = shownUid, statusBarChipIcon = mock())
+                activeNotificationModel(
+                    key = "notif",
+                    uid = shownUid,
+                    statusBarChipIcon = mock(),
+                    promotedContent = PROMOTED_CONTENT,
+                )
             )
 
             // THEN we re-fetch the app visibility state with the new UID, and since that UID is
@@ -257,5 +373,6 @@
 
     companion object {
         private const val UID = 885
+        private val PROMOTED_CONTENT = PromotedNotificationContentModel.Builder("notif1").build()
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
index 8a4ddce..d4910ce 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
@@ -22,22 +22,30 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.kosmos.collectLastValue
 import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.kosmos.useUnconfinedTestDispatcher
 import com.android.systemui.statusbar.StatusBarIconView
 import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
+import com.android.systemui.statusbar.chips.ui.model.ColorsModel
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
 import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
 import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
 import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore
+import com.android.systemui.statusbar.notification.data.repository.UnconfinedFakeHeadsUpRowRepository
 import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus
 import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
 import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
+import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
+import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.runner.RunWith
@@ -47,7 +55,12 @@
 @RunWith(AndroidJUnit4::class)
 @EnableFlags(StatusBarNotifChips.FLAG_NAME)
 class NotifChipsViewModelTest : SysuiTestCase() {
-    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+    private val kosmos =
+        testKosmos().useUnconfinedTestDispatcher().apply {
+            // Don't be in lockscreen so that HUNs are allowed
+            fakeKeyguardTransitionRepository =
+                FakeKeyguardTransitionRepository(initInLockscreen = false, testScope = testScope)
+        }
     private val activeNotificationListRepository = kosmos.activeNotificationListRepository
 
     private val underTest by lazy { kosmos.notifChipsViewModel }
@@ -132,6 +145,36 @@
         }
 
     @Test
+    fun chips_onePromotedNotif_colorMatches() =
+        kosmos.runTest {
+            val latest by collectLastValue(underTest.chips)
+
+            val promotedContentBuilder =
+                PromotedNotificationContentModel.Builder("notif").apply {
+                    this.colors =
+                        PromotedNotificationContentModel.Colors(
+                            backgroundColor = 56,
+                            primaryTextColor = 89,
+                        )
+                }
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "notif",
+                        statusBarChipIcon = mock<StatusBarIconView>(),
+                        promotedContent = promotedContentBuilder.build(),
+                    )
+                )
+            )
+
+            assertThat(latest).hasSize(1)
+            val colors = latest!![0].colors
+            assertThat(colors).isInstanceOf(ColorsModel.Custom::class.java)
+            assertThat((colors as ColorsModel.Custom).backgroundColorInt).isEqualTo(56)
+            assertThat((colors as ColorsModel.Custom).primaryTextColorInt).isEqualTo(89)
+        }
+
+    @Test
     fun chips_onlyForPromotedNotifs() =
         kosmos.runTest {
             val latest by collectLastValue(underTest.chips)
@@ -199,6 +242,54 @@
         }
 
     @Test
+    fun chips_noHeadsUp_showsTime() =
+        kosmos.runTest {
+            val latest by collectLastValue(underTest.chips)
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "notif",
+                        statusBarChipIcon = mock<StatusBarIconView>(),
+                        promotedContent = PromotedNotificationContentModel.Builder("notif").build(),
+                    )
+                )
+            )
+
+            // WHEN there's no HUN
+            kosmos.headsUpNotificationRepository.setNotifications(emptyList())
+
+            // THEN the chip shows the time
+            assertThat(latest!![0])
+                .isInstanceOf(OngoingActivityChipModel.Shown.ShortTimeDelta::class.java)
+        }
+
+    @Test
+    fun chips_hasHeadsUpByUser_onlyShowsIcon() =
+        kosmos.runTest {
+            val latest by collectLastValue(underTest.chips)
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "notif",
+                        statusBarChipIcon = mock<StatusBarIconView>(),
+                        promotedContent = PromotedNotificationContentModel.Builder("notif").build(),
+                    )
+                )
+            )
+
+            // WHEN there's a HUN pinned by a user
+            kosmos.headsUpNotificationRepository.setNotifications(
+                UnconfinedFakeHeadsUpRowRepository(
+                    key = "notif",
+                    pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
+                )
+            )
+
+            assertThat(latest!![0])
+                .isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
+        }
+
+    @Test
     fun chips_clickingChipNotifiesInteractor() =
         kosmos.runTest {
             val latest by collectLastValue(underTest.chips)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
index fe287ef..611ae3d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
@@ -1109,6 +1109,9 @@
             override fun getCurrentCardTopPadding(): Int {
                 return 0
             }
+
+            override fun setHorizontalPaddings(horizontalPadding: Int) {
+            }
         })
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
index 1d7f257..a3ffd91 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
@@ -50,7 +50,6 @@
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderWrapper.DecisionImpl
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderWrapper.FullScreenIntentDecisionImpl
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider
-import com.android.systemui.statusbar.notification.row.NotifBindPipeline.BindCallback
 import com.android.systemui.statusbar.phone.NotificationGroupTestHelper
 import com.android.systemui.testKosmos
 import com.android.systemui.util.concurrency.FakeExecutor
@@ -76,6 +75,7 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.argumentCaptor
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
@@ -315,7 +315,7 @@
 
         // WHEN the notification is added but not yet binding
         collectionListener.onEntryAdded(entry)
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(entry), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(entry), any(), any())
 
         // THEN only promote mEntry
         assertTrue(notifPromoter.shouldPromoteToTopLevel(entry))
@@ -330,7 +330,7 @@
         collectionListener.onEntryAdded(entry)
         beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry))
         beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry))
-        verify(headsUpViewBinder).bindHeadsUpView(eq(entry), any())
+        verify(headsUpViewBinder).bindHeadsUpView(eq(entry), eq(false), any())
 
         // THEN only promote mEntry
         assertTrue(notifPromoter.shouldPromoteToTopLevel(entry))
@@ -382,11 +382,8 @@
         collectionListener.onEntryAdded(entry)
         beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry))
         beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry))
-        verify(headsUpManager, never()).showNotification(entry)
-        withArgCaptor<BindCallback> {
-                verify(headsUpViewBinder).bindHeadsUpView(eq(entry), capture())
-            }
-            .onBindFinished(entry)
+
+        finishBind(entry)
 
         // THEN we tell the HeadsUpManager to show the notification
         verify(headsUpManager).showNotification(entry)
@@ -401,8 +398,8 @@
         beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry))
 
         // THEN we never bind the heads up view or tell HeadsUpManager to show the notification
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(entry), any())
-        verify(headsUpManager, never()).showNotification(entry)
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(entry), any(), any())
+        verify(headsUpManager, never()).showNotification(eq(entry), any())
     }
 
     @Test
@@ -435,8 +432,8 @@
         beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry))
 
         // THEN the notification is never bound or shown
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
-        verify(headsUpManager, never()).showNotification(any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
+        verify(headsUpManager, never()).showNotification(any(), any())
     }
 
     @Test
@@ -471,7 +468,7 @@
             beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry))
 
             finishBind(entry)
-            verify(headsUpManager).showNotification(entry)
+            verify(headsUpManager).showNotification(entry, isPinnedByUser = true)
         }
 
     @Test
@@ -485,8 +482,8 @@
             executor.runAllReady()
             beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry))
 
-            verify(headsUpViewBinder, never()).bindHeadsUpView(eq(entry), any())
-            verify(headsUpManager, never()).showNotification(entry)
+            verify(headsUpViewBinder, never()).bindHeadsUpView(eq(entry), any(), any())
+            verify(headsUpManager, never()).showNotification(eq(entry), any())
         }
 
     @Test
@@ -509,7 +506,7 @@
 
             // THEN it's still shown as heads up
             finishBind(entry)
-            verify(headsUpManager).showNotification(entry)
+            verify(headsUpManager).showNotification(entry, isPinnedByUser = true)
         }
 
     @Test
@@ -525,8 +522,8 @@
             beforeTransformGroupsListener.onBeforeTransformGroups(listOf(promotedEntry))
             beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(promotedEntry))
 
-            verify(headsUpViewBinder, never()).bindHeadsUpView(eq(promotedEntry), any())
-            verify(headsUpManager, never()).showNotification(promotedEntry)
+            verify(headsUpViewBinder, never()).bindHeadsUpView(eq(promotedEntry), any(), any())
+            verify(headsUpManager, never()).showNotification(eq(promotedEntry), any())
 
             // Then a new notification comes in that should be heads up
             setShouldHeadsUp(entry, false)
@@ -544,10 +541,10 @@
 
             // THEN the promoted entry is shown as a HUN, *not* the new entry
             finishBind(promotedEntry)
-            verify(headsUpManager).showNotification(promotedEntry)
+            verify(headsUpManager).showNotification(promotedEntry, isPinnedByUser = true)
 
-            verify(headsUpViewBinder, never()).bindHeadsUpView(eq(entry), any())
-            verify(headsUpManager, never()).showNotification(entry)
+            verify(headsUpViewBinder, never()).bindHeadsUpView(eq(entry), any(), any())
+            verify(headsUpManager, never()).showNotification(eq(entry), any())
         }
 
     @Test
@@ -558,10 +555,10 @@
         collectionListener.onEntryAdded(groupSummary)
         collectionListener.onEntryAdded(groupSibling1)
         beforeTransformGroupsListener.onBeforeTransformGroups(listOf(groupSibling1))
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
         beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(groupSibling1))
 
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any(), any())
         finishBind(groupSibling1)
 
         verify(headsUpManager, never()).showNotification(groupSummary)
@@ -580,10 +577,10 @@
         collectionListener.onEntryAdded(groupSummary)
         collectionListener.onEntryAdded(groupChild1)
         beforeTransformGroupsListener.onBeforeTransformGroups(listOf(groupChild1))
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
         beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(groupChild1))
 
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any(), any())
         finishBind(groupChild1)
 
         verify(headsUpManager, never()).showNotification(groupSummary)
@@ -603,12 +600,12 @@
         collectionListener.onEntryAdded(groupSibling2)
         val entryList = listOf(groupSibling1, groupSibling2)
         beforeTransformGroupsListener.onBeforeTransformGroups(entryList)
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
         beforeFinalizeFilterListener.onBeforeFinalizeFilter(entryList)
 
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any(), any())
         finishBind(groupSibling1)
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any(), any())
 
         // THEN we tell the HeadsUpManager to show the notification
         verify(headsUpManager, never()).showNotification(groupSummary)
@@ -629,12 +626,12 @@
         collectionListener.onEntryAdded(groupChild2)
         val entryList = listOf(groupChild1, groupChild2)
         beforeTransformGroupsListener.onBeforeTransformGroups(entryList)
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
         beforeFinalizeFilterListener.onBeforeFinalizeFilter(entryList)
 
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any(), any())
         finishBind(groupChild1)
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupChild2), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupChild2), any(), any())
 
         // THEN we tell the HeadsUpManager to show the notification
         verify(headsUpManager, never()).showNotification(groupSummary)
@@ -661,7 +658,7 @@
                 .setChildren(listOf(groupSibling1, groupPriority, groupSibling2))
                 .build()
         beforeTransformGroupsListener.onBeforeTransformGroups(listOf(beforeTransformGroup))
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
 
         val afterTransformGroup =
             GroupEntryBuilder()
@@ -672,10 +669,10 @@
             listOf(groupPriority, afterTransformGroup)
         )
 
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any(), any())
         finishBind(groupPriority)
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling1), any())
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling1), any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any(), any())
 
         // THEN we tell the HeadsUpManager to show the notification
         verify(headsUpManager, never()).showNotification(groupSummary)
@@ -702,7 +699,7 @@
                 .setChildren(listOf(groupSibling1, groupPriority, groupSibling2))
                 .build()
         beforeTransformGroupsListener.onBeforeTransformGroups(listOf(beforeTransformGroup))
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
 
         val afterTransformGroup =
             GroupEntryBuilder()
@@ -713,10 +710,10 @@
             listOf(groupPriority, afterTransformGroup)
         )
 
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any(), any())
         finishBind(groupPriority)
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling1), any())
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling1), any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any(), any())
 
         verify(headsUpManager, never()).showNotification(groupSummary)
         verify(headsUpManager).showNotification(groupPriority)
@@ -740,7 +737,7 @@
                 .setChildren(listOf(groupSibling1, groupPriority, groupSibling2))
                 .build()
         beforeTransformGroupsListener.onBeforeTransformGroups(listOf(beforeTransformGroup))
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
 
         val afterTransformGroup =
             GroupEntryBuilder()
@@ -751,10 +748,10 @@
             listOf(groupPriority, afterTransformGroup)
         )
 
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any(), any())
         finishBind(groupPriority)
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling1), any())
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling1), any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any(), any())
 
         verify(headsUpManager, never()).showNotification(groupSummary)
         verify(headsUpManager).showNotification(groupPriority)
@@ -779,7 +776,7 @@
                 .setChildren(listOf(groupSibling1, groupPriority, groupSibling2))
                 .build()
         beforeTransformGroupsListener.onBeforeTransformGroups(listOf(beforeTransformGroup))
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
 
         val afterTransformGroup =
             GroupEntryBuilder()
@@ -791,9 +788,9 @@
         )
 
         finishBind(groupSummary)
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupPriority), any())
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling1), any())
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupPriority), any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling1), any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any(), any())
 
         verify(headsUpManager).showNotification(groupSummary)
         verify(headsUpManager, never()).showNotification(groupPriority)
@@ -816,12 +813,12 @@
                 .setChildren(listOf(groupSibling1, groupSibling2))
                 .build()
         beforeTransformGroupsListener.onBeforeTransformGroups(listOf(groupEntry))
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
         beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(groupEntry))
 
         finishBind(groupSummary)
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling1), any())
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling1), any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any(), any())
 
         verify(headsUpManager).showNotification(groupSummary)
         verify(headsUpManager, never()).showNotification(groupSibling1)
@@ -842,12 +839,12 @@
                 .setChildren(listOf(groupChild1, groupChild2))
                 .build()
         beforeTransformGroupsListener.onBeforeTransformGroups(listOf(groupEntry))
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
         beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(groupEntry))
 
         finishBind(groupSummary)
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupChild1), any())
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupChild2), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupChild1), any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupChild2), any(), any())
 
         verify(headsUpManager).showNotification(groupSummary)
         verify(headsUpManager, never()).showNotification(groupChild1)
@@ -871,12 +868,12 @@
                 .setChildren(listOf(groupChild1, groupChild2))
                 .build()
         beforeTransformGroupsListener.onBeforeTransformGroups(listOf(groupEntry))
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
         beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(groupEntry))
 
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any(), any())
         finishBind(groupChild1)
-        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupChild2), any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupChild2), any(), any())
 
         verify(headsUpManager, never()).showNotification(groupSummary)
         verify(headsUpManager).showNotification(groupChild1)
@@ -900,7 +897,7 @@
 
         // THEN the notification is shown
         finishBind(entry)
-        verify(headsUpManager).showNotification(entry)
+        verify(headsUpManager).showNotification(entry, isPinnedByUser = false)
     }
 
     @Test
@@ -917,8 +914,8 @@
         beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry))
 
         // THEN the notification is never bound or shown
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
-        verify(headsUpManager, never()).showNotification(any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
+        verify(headsUpManager, never()).showNotification(any(), any())
     }
 
     @Test
@@ -938,7 +935,7 @@
 
         // THEN the notification is shown
         finishBind(entry)
-        verify(headsUpManager).showNotification(entry)
+        verify(headsUpManager).showNotification(entry, isPinnedByUser = false)
     }
 
     @Test
@@ -958,8 +955,8 @@
         beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry))
 
         // THEN the notification is never bound or shown
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
-        verify(headsUpManager, never()).showNotification(any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
+        verify(headsUpManager, never()).showNotification(any(), any())
     }
 
     @Test
@@ -1022,8 +1019,8 @@
 
         // THEN it should full screen and log but it should NOT HUN
         verify(launchFullScreenIntentProvider).launchFullScreenIntent(entry)
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
-        verify(headsUpManager, never()).showNotification(any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
+        verify(headsUpManager, never()).showNotification(any(), any())
         verifyLoggedFullScreenIntentDecision(
             entry,
             FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE,
@@ -1063,8 +1060,8 @@
 
         // THEN it should still not yet full screen or HUN
         verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any())
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
-        verify(headsUpManager, never()).showNotification(any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
+        verify(headsUpManager, never()).showNotification(any(), any())
 
         // Same decision as before; is not logged
         verifyNoFullScreenIntentDecisionLogged()
@@ -1080,8 +1077,8 @@
 
         // THEN it should full screen and log but it should NOT HUN
         verify(launchFullScreenIntentProvider).launchFullScreenIntent(entry)
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
-        verify(headsUpManager, never()).showNotification(any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
+        verify(headsUpManager, never()).showNotification(any(), any())
         verifyLoggedFullScreenIntentDecision(
             entry,
             FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE,
@@ -1107,8 +1104,8 @@
 
         // THEN it should NOT full screen or HUN
         verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any())
-        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any())
-        verify(headsUpManager, never()).showNotification(any())
+        verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any(), any())
+        verify(headsUpManager, never()).showNotification(any(), any())
 
         // NOW the DND logic changes and FSI and HUN are available
         clearInvocations(launchFullScreenIntentProvider)
@@ -1121,7 +1118,7 @@
         // VERIFY that the FSI didn't happen, but that we do HUN
         verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any())
         finishBind(entry)
-        verify(headsUpManager).showNotification(entry)
+        verify(headsUpManager).showNotification(entry, isPinnedByUser = false)
     }
 
     @Test
@@ -1206,10 +1203,12 @@
     }
 
     private fun finishBind(entry: NotificationEntry) {
-        verify(headsUpManager, never()).showNotification(entry)
-        withArgCaptor<BindCallback> {
-                verify(headsUpViewBinder).bindHeadsUpView(eq(entry), capture())
+        verify(headsUpManager, never()).showNotification(eq(entry), any())
+        val isPinnedByUserCaptor = argumentCaptor<Boolean>()
+        withArgCaptor<HeadsUpViewBinder.HeadsUpBindCallback> {
+                verify(headsUpViewBinder)
+                    .bindHeadsUpView(eq(entry), isPinnedByUserCaptor.capture(), capture())
             }
-            .onBindFinished(entry)
+            .onHeadsUpBindFinished(entry, isPinnedByUserCaptor.firstValue)
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
index 68798a8..9e7befd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
@@ -27,15 +27,28 @@
 import android.platform.test.flag.junit.FlagsParameterization
 import android.service.notification.StatusBarNotification
 import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.compose.animation.scene.SceneKey
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.keyguardUpdateMonitor
 import com.android.server.notification.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING
 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.deviceentry.data.repository.fakeDeviceEntryRepository
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.flags.andSceneContainer
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.statusbar.fakeStatusBarStateController
 import com.android.systemui.plugins.statusbar.statusBarStateController
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.statusbar.NotificationLockscreenUserManager
 import com.android.systemui.statusbar.RankingBuilder
 import com.android.systemui.statusbar.StatusBarState
@@ -60,11 +73,16 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.withArgCaptor
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.kotlin.any
+import org.mockito.kotlin.clearInvocations
 import org.mockito.kotlin.eq
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.never
@@ -86,6 +104,8 @@
             statusBarStateController = fakeStatusBarStateController
         }
 
+    val testScope = kosmos.testScope
+
     val dynamicPrivacyController: DynamicPrivacyController = kosmos.mockDynamicPrivacyController
     val lockscreenUserManager: NotificationLockscreenUserManager =
         kosmos.notificationLockscreenUserManager
@@ -95,7 +115,12 @@
         kosmos.fakeStatusBarStateController
     val sensitiveNotificationProtectionController: SensitiveNotificationProtectionController =
         kosmos.mockSensitiveNotificationProtectionController
-    val sceneInteractor: SceneInteractor = kosmos.sceneInteractor
+    val deviceEntryInteractor: DeviceEntryInteractor
+        get() = kosmos.deviceEntryInteractor
+
+    val faceAuthRepository = kosmos.fakeDeviceEntryFaceAuthRepository
+    val sceneInteractor: SceneInteractor
+        get() = kosmos.sceneInteractor
 
     val coordinator: SensitiveContentCoordinator by lazy { kosmos.sensitiveContentCoordinator }
 
@@ -112,592 +137,696 @@
     }
 
     @Test
-    fun onDynamicPrivacyChanged_invokeInvalidationListener() {
-        coordinator.attach(pipeline)
-        val invalidator =
-            withArgCaptor<Invalidator> { verify(pipeline).addPreRenderInvalidator(capture()) }
-        val dynamicPrivacyListener =
-            withArgCaptor<DynamicPrivacyController.Listener> {
-                verify(dynamicPrivacyController).addListener(capture())
-            }
+    @EnableSceneContainer
+    fun onLockscreenDynamicallyUnlocked_invokeInvalidationListener() =
+        testScope.runTest {
+            // Setup
+            coordinator.attach(pipeline)
+            val invalidator =
+                withArgCaptor<Invalidator> { verify(pipeline).addPreRenderInvalidator(capture()) }
+            val invalidationListener = mock<Pluggable.PluggableListener<Invalidator>>()
+            invalidator.setInvalidationListener(invalidationListener)
 
-        val invalidationListener = mock<Pluggable.PluggableListener<Invalidator>>()
-        invalidator.setInvalidationListener(invalidationListener)
+            // Given the lockscreen is shown
+            setupLockScreen(canSwipeUp = false)
+            clearInvocations(invalidationListener)
 
-        dynamicPrivacyListener.onDynamicPrivacyChanged()
+            // When the device gets unlocked
+            faceAuthRepository.isAuthenticated.value = true
+            runCurrent()
 
-        verify(invalidationListener).onPluggableInvalidated(eq(invalidator), any())
-    }
+            // Then the invalidationListener is called
+            verify(invalidationListener).onPluggableInvalidated(eq(invalidator), any())
+        }
+
+    @Test
+    @DisableSceneContainer
+    fun onDynamicPrivacyChanged_invokeInvalidationListener() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val invalidator =
+                withArgCaptor<Invalidator> { verify(pipeline).addPreRenderInvalidator(capture()) }
+            val dynamicPrivacyListener =
+                withArgCaptor<DynamicPrivacyController.Listener> {
+                    verify(dynamicPrivacyController).addListener(capture())
+                }
+
+            val invalidationListener = mock<Pluggable.PluggableListener<Invalidator>>()
+            invalidator.setInvalidationListener(invalidationListener)
+
+            dynamicPrivacyListener.onDynamicPrivacyChanged()
+
+            verify(invalidationListener).onPluggableInvalidated(eq(invalidator), any())
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
-    fun onSensitiveStateChanged_invokeInvalidationListener() {
-        coordinator.attach(pipeline)
-        val invalidator =
-            withArgCaptor<Invalidator> { verify(pipeline).addPreRenderInvalidator(capture()) }
-        val onSensitiveStateChangedListener =
-            withArgCaptor<Runnable> {
-                verify(sensitiveNotificationProtectionController)
-                    .registerSensitiveStateListener(capture())
-            }
+    fun onSensitiveStateChanged_invokeInvalidationListener() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val invalidator =
+                withArgCaptor<Invalidator> { verify(pipeline).addPreRenderInvalidator(capture()) }
+            val onSensitiveStateChangedListener =
+                withArgCaptor<Runnable> {
+                    verify(sensitiveNotificationProtectionController)
+                        .registerSensitiveStateListener(capture())
+                }
 
-        val invalidationListener = mock<Pluggable.PluggableListener<Invalidator>>()
-        invalidator.setInvalidationListener(invalidationListener)
+            val invalidationListener = mock<Pluggable.PluggableListener<Invalidator>>()
+            invalidator.setInvalidationListener(invalidationListener)
 
-        onSensitiveStateChangedListener.run()
+            onSensitiveStateChangedListener.run()
 
-        verify(invalidationListener).onPluggableInvalidated(eq(invalidator), any())
-    }
+            verify(invalidationListener).onPluggableInvalidated(eq(invalidator), any())
+        }
 
     @Test
     @DisableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
-    fun screenshareSecretFilter_flagDisabled_filterNoAdded() {
-        coordinator.attach(pipeline)
+    fun screenshareSecretFilter_flagDisabled_filterNoAdded() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
 
-        verify(pipeline, never()).addFinalizeFilter(any())
-    }
+            verify(pipeline, never()).addFinalizeFilter(any())
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
-    fun screenshareSecretFilter_sensitiveInctive_noFiltersSecret() {
-        whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(false)
+    fun screenshareSecretFilter_sensitiveInctive_noFiltersSecret() =
+        testScope.runTest {
+            whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+                .thenReturn(false)
 
-        coordinator.attach(pipeline)
-        val filter = withArgCaptor<NotifFilter> { verify(pipeline).addFinalizeFilter(capture()) }
+            coordinator.attach(pipeline)
+            val filter =
+                withArgCaptor<NotifFilter> { verify(pipeline).addFinalizeFilter(capture()) }
 
-        val defaultNotification = createNotificationEntry("test", false, false)
-        val notificationWithSecretVisibility = createNotificationEntry("test", true, false)
-        val notificationOnSecretChannel = createNotificationEntry("test", false, true)
+            val defaultNotification = createNotificationEntry("test", false, false)
+            val notificationWithSecretVisibility = createNotificationEntry("test", true, false)
+            val notificationOnSecretChannel = createNotificationEntry("test", false, true)
 
-        assertFalse(filter.shouldFilterOut(defaultNotification, 0))
-        assertFalse(filter.shouldFilterOut(notificationWithSecretVisibility, 0))
-        assertFalse(filter.shouldFilterOut(notificationOnSecretChannel, 0))
-    }
+            assertFalse(filter.shouldFilterOut(defaultNotification, 0))
+            assertFalse(filter.shouldFilterOut(notificationWithSecretVisibility, 0))
+            assertFalse(filter.shouldFilterOut(notificationOnSecretChannel, 0))
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
-    fun screenshareSecretFilter_sensitiveActive_filtersSecret() {
-        whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+    fun screenshareSecretFilter_sensitiveActive_filtersSecret() =
+        testScope.runTest {
+            whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+                .thenReturn(true)
 
-        coordinator.attach(pipeline)
-        val filter = withArgCaptor<NotifFilter> { verify(pipeline).addFinalizeFilter(capture()) }
+            coordinator.attach(pipeline)
+            val filter =
+                withArgCaptor<NotifFilter> { verify(pipeline).addFinalizeFilter(capture()) }
 
-        val defaultNotification = createNotificationEntry("test", false, false)
-        val notificationWithSecretVisibility = createNotificationEntry("test", true, false)
-        val notificationOnSecretChannel = createNotificationEntry("test", false, true)
+            val defaultNotification = createNotificationEntry("test", false, false)
+            val notificationWithSecretVisibility = createNotificationEntry("test", true, false)
+            val notificationOnSecretChannel = createNotificationEntry("test", false, true)
 
-        assertFalse(filter.shouldFilterOut(defaultNotification, 0))
-        assertTrue(filter.shouldFilterOut(notificationWithSecretVisibility, 0))
-        assertTrue(filter.shouldFilterOut(notificationOnSecretChannel, 0))
-    }
+            assertFalse(filter.shouldFilterOut(defaultNotification, 0))
+            assertTrue(filter.shouldFilterOut(notificationWithSecretVisibility, 0))
+            assertTrue(filter.shouldFilterOut(notificationOnSecretChannel, 0))
+        }
 
     @Test
-    fun onBeforeRenderList_deviceUnlocked_notifDoesNotNeedRedaction() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceUnlocked_notifDoesNotNeedRedaction() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
-        val entry = fakeNotification(1, false)
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(true)
+            setupLockScreen(canSwipeUp = false)
+            val entry = fakeNotification(1, false)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(false, false)
-    }
+            verify(entry.representativeEntry!!).setSensitive(false, false)
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
-    fun onBeforeRenderList_deviceUnlocked_notifDoesNotNeedRedaction_sensitiveActive() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceUnlocked_notifDoesNotNeedRedaction_sensitiveActive() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
-        val entry = fakeNotification(1, false)
-        whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(true)
+            setupLockScreen(canSwipeUp = false)
+            val entry = fakeNotification(1, false)
+            whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+                .thenReturn(true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(false, true)
-        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
-    }
+            verify(entry.representativeEntry!!).setSensitive(false, true)
+            verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
-    fun onBeforeRenderList_deviceUnlocked_notifDoesNotNeedRedaction_shouldProtectNotification() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceUnlocked_notifDoesNotNeedRedaction_shouldProtectNotification() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
-        val entry = fakeNotification(1, false)
-        whenever(
-                sensitiveNotificationProtectionController.shouldProtectNotification(
-                    entry.getRepresentativeEntry()
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(true)
+            setupLockScreen(canSwipeUp = false)
+            val entry = fakeNotification(1, false)
+            whenever(
+                    sensitiveNotificationProtectionController.shouldProtectNotification(
+                        entry.getRepresentativeEntry()
+                    )
                 )
-            )
-            .thenReturn(true)
+                .thenReturn(true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(true, false)
-        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
-    }
+            verify(entry.representativeEntry!!).setSensitive(true, false)
+            verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
+        }
 
     @Test
-    fun onBeforeRenderList_deviceUnlocked_notifWouldNeedRedaction() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceUnlocked_notifWouldNeedRedaction() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
-        val entry = fakeNotification(1, true)
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(true)
+            setupLockScreen(canSwipeUp = false)
+            val entry = fakeNotification(1, true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(false, false)
-    }
+            verify(entry.representativeEntry!!).setSensitive(false, false)
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
-    fun onBeforeRenderList_deviceUnlocked_notifWouldNeedRedaction_sensitiveActive() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceUnlocked_notifWouldNeedRedaction_sensitiveActive() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
-        val entry = fakeNotification(1, true)
-        whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(true)
+            setupLockScreen(canSwipeUp = false)
+            val entry = fakeNotification(1, true)
+            whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+                .thenReturn(true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(false, true)
-        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
-    }
+            verify(entry.representativeEntry!!).setSensitive(false, true)
+            verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
-    fun onBeforeRenderList_deviceUnlocked_notifWouldNeedRedaction_shouldProtectNotification() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceUnlocked_notifWouldNeedRedaction_shouldProtectNotification() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
-        val entry = fakeNotification(1, true)
-        whenever(
-                sensitiveNotificationProtectionController.shouldProtectNotification(
-                    entry.getRepresentativeEntry()
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(true)
+            setupLockScreen(canSwipeUp = false)
+            val entry = fakeNotification(1, true)
+            whenever(
+                    sensitiveNotificationProtectionController.shouldProtectNotification(
+                        entry.getRepresentativeEntry()
+                    )
                 )
-            )
-            .thenReturn(true)
+                .thenReturn(true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(true, false)
-        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
-    }
+            verify(entry.representativeEntry!!).setSensitive(true, false)
+            verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
+        }
 
     @Test
-    fun onBeforeRenderList_deviceLocked_userAllowsPublicNotifs() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceLocked_userAllowsPublicNotifs() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
-        val entry = fakeNotification(1, false)
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(true)
+            setupLockScreen(canSwipeUp = false)
+            val entry = fakeNotification(1, false)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(false, false)
-    }
+            verify(entry.representativeEntry!!).setSensitive(false, false)
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
-    fun onBeforeRenderList_deviceLocked_userAllowsPublicNotifs_sensitiveActive() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceLocked_userAllowsPublicNotifs_sensitiveActive() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
-        val entry = fakeNotification(1, false)
-        whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(true)
+            setupLockScreen(canSwipeUp = false)
+            val entry = fakeNotification(1, false)
+            whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+                .thenReturn(true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(false, true)
-        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
-    }
+            verify(entry.representativeEntry!!).setSensitive(false, true)
+            verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
-    fun onBeforeRenderList_deviceLocked_userAllowsPublicNotifs_shouldProtectNotification() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceLocked_userAllowsPublicNotifs_shouldProtectNotification() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
-        val entry = fakeNotification(1, false)
-        whenever(
-                sensitiveNotificationProtectionController.shouldProtectNotification(
-                    entry.getRepresentativeEntry()
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(true)
+            setupLockScreen(canSwipeUp = false)
+            val entry = fakeNotification(1, false)
+            whenever(
+                    sensitiveNotificationProtectionController.shouldProtectNotification(
+                        entry.getRepresentativeEntry()
+                    )
                 )
-            )
-            .thenReturn(true)
+                .thenReturn(true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(true, false)
-        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
-    }
+            verify(entry.representativeEntry!!).setSensitive(true, false)
+            verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
+        }
 
     @Test
-    fun onBeforeRenderList_deviceLocked_userDisallowsPublicNotifs_notifDoesNotNeedRedaction() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceLocked_userDisallowsPublicNotifs_notifDoesNotNeedRedaction() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
-        val entry = fakeNotification(1, false)
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(false)
+            setupLockScreen(canSwipeUp = false)
+            val entry = fakeNotification(1, false)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(false, true)
-    }
+            verify(entry.representativeEntry!!).setSensitive(false, true)
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
     @Suppress("ktlint:standard:max-line-length")
-    fun onBeforeRenderList_deviceLocked_userDisallowsPublicNotifs_notifDoesNotNeedRedaction_sensitiveActive() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceLocked_userDisallowsPublicNotifs_notifDoesNotNeedRedaction_sensitiveActive() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
-        val entry = fakeNotification(1, false)
-        whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(false)
+            setupLockScreen(canSwipeUp = false)
+            val entry = fakeNotification(1, false)
+            whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+                .thenReturn(true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(false, true)
-        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
-    }
+            verify(entry.representativeEntry!!).setSensitive(false, true)
+            verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
     @Suppress("ktlint:standard:max-line-length")
-    fun onBeforeRenderList_deviceLocked_userDisallowsPublicNotifs_notifDoesNotNeedRedaction_shouldProtectNotification() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceLocked_userDisallowsPublicNotifs_notifDoesNotNeedRedaction_shouldProtectNotification() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
-        val entry = fakeNotification(1, false)
-        whenever(
-                sensitiveNotificationProtectionController.shouldProtectNotification(
-                    entry.getRepresentativeEntry()
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(false)
+            setupLockScreen(canSwipeUp = false)
+            val entry = fakeNotification(1, false)
+            whenever(
+                    sensitiveNotificationProtectionController.shouldProtectNotification(
+                        entry.getRepresentativeEntry()
+                    )
                 )
-            )
-            .thenReturn(true)
+                .thenReturn(true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(true, true)
-        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
-    }
+            verify(entry.representativeEntry!!).setSensitive(true, true)
+            verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
+        }
 
     @Test
-    fun onBeforeRenderList_deviceLocked_notifNeedsRedaction() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceLocked_notifNeedsRedaction() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
-        val entry = fakeNotification(1, true)
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(false)
+            setupLockScreen(canSwipeUp = false)
+            val entry = fakeNotification(1, true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(true, true)
-    }
+            verify(entry.representativeEntry!!).setSensitive(true, true)
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
-    fun onBeforeRenderList_deviceLocked_notifNeedsRedaction_sensitiveActive() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceLocked_notifNeedsRedaction_sensitiveActive() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
-        val entry = fakeNotification(1, true)
-        whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(false)
+            setupLockScreen(canSwipeUp = false)
+            val entry = fakeNotification(1, true)
+            whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+                .thenReturn(true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(true, true)
-        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
-    }
+            verify(entry.representativeEntry!!).setSensitive(true, true)
+            verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
-    fun onBeforeRenderList_deviceLocked_notifNeedsRedaction_shouldProtectNotification() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceLocked_notifNeedsRedaction_shouldProtectNotification() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
-        val entry = fakeNotification(1, true)
-        whenever(
-                sensitiveNotificationProtectionController.shouldProtectNotification(
-                    entry.getRepresentativeEntry()
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(false)
+            setupLockScreen(canSwipeUp = false)
+            val entry = fakeNotification(1, true)
+            whenever(
+                    sensitiveNotificationProtectionController.shouldProtectNotification(
+                        entry.getRepresentativeEntry()
+                    )
                 )
-            )
-            .thenReturn(true)
+                .thenReturn(true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(true, true)
-        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
-    }
+            verify(entry.representativeEntry!!).setSensitive(true, true)
+            verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
+        }
 
     @Test
-    fun onBeforeRenderList_deviceDynamicallyUnlocked_notifNeedsRedaction() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceDynamicallyUnlocked_notifNeedsRedaction() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
-        val entry = fakeNotification(1, true)
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(false)
+            setupLockScreen(canSwipeUp = true)
+            val entry = fakeNotification(1, true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(false, true)
-    }
+            verify(entry.representativeEntry!!).setSensitive(false, true)
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
-    fun onBeforeRenderList_deviceDynamicallyUnlocked_notifNeedsRedaction_sensitiveActive() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceDynamicallyUnlocked_notifNeedsRedaction_sensitiveActive() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
-        val entry = fakeNotification(1, true)
-        whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(false)
+            setupLockScreen(canSwipeUp = true)
+            val entry = fakeNotification(1, true)
+            whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+                .thenReturn(true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(false, true)
-        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
-    }
+            verify(entry.representativeEntry!!).setSensitive(false, true)
+            verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
     @Suppress("ktlint:standard:max-line-length")
-    fun onBeforeRenderList_deviceDynamicallyUnlocked_notifNeedsRedaction_shouldProtectNotification() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceDynamicallyUnlocked_notifNeedsRedaction_shouldProtectNotification() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
-        val entry = fakeNotification(1, true)
-        whenever(
-                sensitiveNotificationProtectionController.shouldProtectNotification(
-                    entry.getRepresentativeEntry()
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(false)
+            setupLockScreen(canSwipeUp = true)
+            val entry = fakeNotification(1, true)
+            whenever(
+                    sensitiveNotificationProtectionController.shouldProtectNotification(
+                        entry.getRepresentativeEntry()
+                    )
                 )
-            )
-            .thenReturn(true)
+                .thenReturn(true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(true, true)
-        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
-    }
+            verify(entry.representativeEntry!!).setSensitive(true, true)
+            verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
+        }
 
     @Test
-    fun onBeforeRenderList_deviceDynamicallyUnlocked_notifUserNeedsWorkChallenge() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceDynamicallyUnlocked_notifUserNeedsWorkChallenge() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
-        whenever(lockscreenUserManager.needsSeparateWorkChallenge(2)).thenReturn(true)
-        val entry = fakeNotification(2, true)
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(false)
+            setupLockScreen(canSwipeUp = true)
+            whenever(lockscreenUserManager.needsSeparateWorkChallenge(2)).thenReturn(true)
+            val entry = fakeNotification(2, true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(true, true)
-    }
+            verify(entry.representativeEntry!!).setSensitive(true, true)
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
-    fun onBeforeRenderList_deviceDynamicallyUnlocked_notifUserNeedsWorkChallenge_sensitiveActive() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceDynamicallyUnlocked_notifUserNeedsWorkChallenge_sensitiveActive() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
-        whenever(lockscreenUserManager.needsSeparateWorkChallenge(2)).thenReturn(true)
-        val entry = fakeNotification(2, true)
-        whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(false)
+            setupLockScreen(canSwipeUp = true)
+            whenever(lockscreenUserManager.needsSeparateWorkChallenge(2)).thenReturn(true)
+            val entry = fakeNotification(2, true)
+            whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+                .thenReturn(true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(true, true)
-        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
-    }
+            verify(entry.representativeEntry!!).setSensitive(true, true)
+            verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
+        }
 
     @Test
     @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
     @Suppress("ktlint:standard:max-line-length")
-    fun onBeforeRenderList_deviceDynamicallyUnlocked_notifUserNeedsWorkChallenge_shouldProtectNotification() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceDynamicallyUnlocked_notifUserNeedsWorkChallenge_shouldProtectNotification() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
-        whenever(lockscreenUserManager.needsSeparateWorkChallenge(2)).thenReturn(true)
-        val entry = fakeNotification(2, true)
-        whenever(
-                sensitiveNotificationProtectionController.shouldProtectNotification(
-                    entry.getRepresentativeEntry()
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(false)
+            setupLockScreen(canSwipeUp = true)
+            whenever(lockscreenUserManager.needsSeparateWorkChallenge(2)).thenReturn(true)
+            val entry = fakeNotification(2, true)
+            whenever(
+                    sensitiveNotificationProtectionController.shouldProtectNotification(
+                        entry.getRepresentativeEntry()
+                    )
                 )
-            )
-            .thenReturn(true)
+                .thenReturn(true)
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!).setSensitive(true, true)
-        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
-    }
+            verify(entry.representativeEntry!!).setSensitive(true, true)
+            verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
+        }
 
     @Test
-    fun onBeforeRenderList_deviceDynamicallyUnlocked_deviceBiometricBypassingLockScreen() {
-        coordinator.attach(pipeline)
-        val onBeforeRenderListListener =
-            withArgCaptor<OnBeforeRenderListListener> {
-                verify(pipeline).addOnBeforeRenderListListener(capture())
-            }
+    fun onBeforeRenderList_deviceDynamicallyUnlocked_deviceBiometricBypassingLockScreen() =
+        testScope.runTest {
+            coordinator.attach(pipeline)
+            val onBeforeRenderListListener =
+                withArgCaptor<OnBeforeRenderListListener> {
+                    verify(pipeline).addOnBeforeRenderListListener(capture())
+                }
 
-        whenever(lockscreenUserManager.currentUserId).thenReturn(1)
-        whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
-        whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
-        whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
-        whenever(keyguardUpdateMonitor.getUserUnlockedWithBiometricAndIsBypassing(any()))
-            .thenReturn(true)
-        val entry = fakeNotification(2, true)
-        whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
-        whenever(sensitiveNotificationProtectionController.shouldProtectNotification(any()))
-            .thenReturn(true)
-        statusBarStateController.state = StatusBarState.KEYGUARD
+            whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+            whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+            whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+                .thenReturn(false)
+            setupLockScreen(canSwipeUp = true)
+            whenever(keyguardUpdateMonitor.getUserUnlockedWithBiometricAndIsBypassing(any()))
+                .thenReturn(true)
+            val entry = fakeNotification(2, true)
+            whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+                .thenReturn(true)
+            whenever(sensitiveNotificationProtectionController.shouldProtectNotification(any()))
+                .thenReturn(true)
+            statusBarStateController.state = StatusBarState.KEYGUARD
 
-        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+            onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
-        verify(entry.representativeEntry!!, never()).setSensitive(any(), any())
-        verify(entry.representativeEntry!!.row!!, never()).setPublicExpanderVisible(any())
+            verify(entry.representativeEntry!!, never()).setSensitive(any(), any())
+            verify(entry.representativeEntry!!.row!!, never()).setPublicExpanderVisible(any())
+        }
+
+    private fun TestScope.setupLockScreen(canSwipeUp: Boolean) {
+        if (SceneContainerFlag.isEnabled) {
+            val authMethod =
+                if (canSwipeUp) AuthenticationMethodModel.None
+                else AuthenticationMethodModel.Password
+            kosmos.fakeAuthenticationRepository.setAuthenticationMethod(authMethod)
+            kosmos.fakeDeviceEntryRepository.setLockscreenEnabled(true)
+            switchToScene(Scenes.Lockscreen)
+        } else {
+            whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(canSwipeUp)
+        }
+    }
+
+    private fun TestScope.switchToScene(sceneKey: SceneKey) {
+        sceneInteractor.changeScene(sceneKey, "reason")
+        sceneInteractor.setTransitionState(flowOf(ObservableTransitionState.Idle(sceneKey)))
+        runCurrent()
     }
 
     private fun fakeNotification(notifUserId: Int, needsRedaction: Boolean): ListEntry {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt
index dc0231f..22ef408 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt
@@ -28,6 +28,7 @@
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.shade.data.repository.fakeShadeRepository
 import com.android.systemui.shade.shadeTestUtil
 import com.android.systemui.statusbar.notification.data.repository.FakeHeadsUpRowRepository
 import com.android.systemui.statusbar.notification.data.repository.notificationsKeyguardViewStateRepository
@@ -409,76 +410,101 @@
         }
 
     @Test
-    fun showHeadsUpStatusBar_true() =
+    fun statusBarHeadsUpState_pinnedBySystem() =
         testScope.runTest {
-            val showHeadsUpStatusBar by collectLastValue(underTest.showHeadsUpStatusBar)
+            val statusBarHeadsUpState by collectLastValue(underTest.statusBarHeadsUpState)
 
-            // WHEN a row is pinned
-            headsUpRepository.setNotifications(fakeHeadsUpRowRepository("key 0", isPinned = true))
+            headsUpRepository.setNotifications(
+                FakeHeadsUpRowRepository(key = "key 0", pinnedStatus = PinnedStatus.PinnedBySystem)
+            )
+            runCurrent()
 
-            assertThat(showHeadsUpStatusBar).isTrue()
+            assertThat(statusBarHeadsUpState).isEqualTo(PinnedStatus.PinnedBySystem)
         }
 
     @Test
-    fun showHeadsUpStatusBar_withoutPinnedNotifications_false() =
+    fun statusBarHeadsUpState_pinnedByUser() =
         testScope.runTest {
-            val showHeadsUpStatusBar by collectLastValue(underTest.showHeadsUpStatusBar)
+            val statusBarHeadsUpState by collectLastValue(underTest.statusBarHeadsUpState)
 
-            // WHEN no row is pinned
-            headsUpRepository.setNotifications(fakeHeadsUpRowRepository("key 0", isPinned = false))
+            headsUpRepository.setNotifications(
+                FakeHeadsUpRowRepository(key = "key 0", pinnedStatus = PinnedStatus.PinnedByUser)
+            )
+            runCurrent()
 
-            assertThat(showHeadsUpStatusBar).isFalse()
+            assertThat(statusBarHeadsUpState).isEqualTo(PinnedStatus.PinnedByUser)
         }
 
     @Test
-    fun showHeadsUpStatusBar_whenShadeExpanded_false() =
+    fun statusBarHeadsUpState_withoutPinnedNotifications_notPinned() =
         testScope.runTest {
-            val showHeadsUpStatusBar by collectLastValue(underTest.showHeadsUpStatusBar)
+            val statusBarHeadsUpState by collectLastValue(underTest.statusBarHeadsUpState)
+
+            headsUpRepository.setNotifications(
+                FakeHeadsUpRowRepository(key = "key 0", PinnedStatus.NotPinned)
+            )
+            runCurrent()
+
+            assertThat(statusBarHeadsUpState).isEqualTo(PinnedStatus.NotPinned)
+        }
+
+    @Test
+    fun statusBarHeadsUpState_whenShadeExpanded_false() =
+        testScope.runTest {
+            val statusBarHeadsUpState by collectLastValue(underTest.statusBarHeadsUpState)
 
             // WHEN a row is pinned
             headsUpRepository.setNotifications(fakeHeadsUpRowRepository("key 0", isPinned = true))
+            runCurrent()
             // AND the shade is expanded
             shadeTestUtil.setShadeExpansion(1.0f)
+            // Needed if SceneContainer flag is off: `ShadeTestUtil.setShadeExpansion(1f)`
+            // incorrectly causes `ShadeInteractor.isShadeFullyCollapsed` to emit `true`, when it
+            // should emit `false`.
+            kosmos.fakeShadeRepository.setLegacyShadeExpansion(1.0f)
 
-            assertThat(showHeadsUpStatusBar).isFalse()
+            assertThat(statusBarHeadsUpState!!.isPinned).isFalse()
         }
 
     @Test
-    fun showHeadsUpStatusBar_notificationsAreHidden_false() =
+    fun statusBarHeadsUpState_notificationsAreHidden_false() =
         testScope.runTest {
-            val showHeadsUpStatusBar by collectLastValue(underTest.showHeadsUpStatusBar)
+            val statusBarHeadsUpState by collectLastValue(underTest.statusBarHeadsUpState)
 
             // WHEN a row is pinned
             headsUpRepository.setNotifications(fakeHeadsUpRowRepository("key 0", isPinned = true))
+            runCurrent()
             // AND the notifications are hidden
             keyguardViewStateRepository.areNotificationsFullyHidden.value = true
 
-            assertThat(showHeadsUpStatusBar).isFalse()
+            assertThat(statusBarHeadsUpState!!.isPinned).isFalse()
         }
 
     @Test
-    fun showHeadsUpStatusBar_onLockScreen_false() =
+    fun statusBarHeadsUpState_onLockScreen_false() =
         testScope.runTest {
-            val showHeadsUpStatusBar by collectLastValue(underTest.showHeadsUpStatusBar)
+            val statusBarHeadsUpState by collectLastValue(underTest.statusBarHeadsUpState)
 
             // WHEN a row is pinned
             headsUpRepository.setNotifications(fakeHeadsUpRowRepository("key 0", isPinned = true))
+            runCurrent()
             // AND the lock screen is shown
             keyguardTransitionRepository.emitInitialStepsFromOff(
                 to = KeyguardState.LOCKSCREEN,
                 testSetup = true,
             )
 
-            assertThat(showHeadsUpStatusBar).isFalse()
+            assertThat(statusBarHeadsUpState!!.isPinned).isFalse()
         }
 
     @Test
-    fun showHeadsUpStatusBar_onByPassLockScreen_true() =
+    fun statusBarHeadsUpState_onByPassLockScreen_true() =
         testScope.runTest {
-            val showHeadsUpStatusBar by collectLastValue(underTest.showHeadsUpStatusBar)
+            val statusBarHeadsUpState by collectLastValue(underTest.statusBarHeadsUpState)
 
             // WHEN a row is pinned
             headsUpRepository.setNotifications(fakeHeadsUpRowRepository("key 0", isPinned = true))
+            runCurrent()
             // AND the lock screen is shown
             keyguardTransitionRepository.emitInitialStepsFromOff(
                 to = KeyguardState.LOCKSCREEN,
@@ -487,13 +513,13 @@
             // AND bypass is enabled
             faceAuthRepository.isBypassEnabled.value = true
 
-            assertThat(showHeadsUpStatusBar).isTrue()
+            assertThat(statusBarHeadsUpState!!.isPinned).isTrue()
         }
 
     @Test
-    fun showHeadsUpStatusBar_onByPassLockScreen_withoutNotifications_false() =
+    fun statusBarHeadsUpState_onByPassLockScreen_withoutNotifications_false() =
         testScope.runTest {
-            val showHeadsUpStatusBar by collectLastValue(underTest.showHeadsUpStatusBar)
+            val statusBarHeadsUpState by collectLastValue(underTest.statusBarHeadsUpState)
 
             // WHEN no pinned rows
             // AND the lock screen is shown
@@ -504,7 +530,7 @@
             // AND bypass is enabled
             faceAuthRepository.isBypassEnabled.value = true
 
-            assertThat(showHeadsUpStatusBar).isFalse()
+            assertThat(statusBarHeadsUpState!!.isPinned).isFalse()
         }
 
     private fun fakeHeadsUpRowRepository(key: String, isPinned: Boolean = false) =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java
index c9ca67e..615f4b01 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java
@@ -78,7 +78,7 @@
     public void setUp() {
         if (NotifRedesignFooter.isEnabled()) {
             mView = (FooterView) LayoutInflater.from(mSpyContext).inflate(
-                    R.layout.status_bar_notification_footer_redesign, null, false);
+                    R.layout.notification_2025_footer, null, false);
         } else {
             mView = (FooterView) LayoutInflater.from(mSpyContext).inflate(
                     R.layout.status_bar_notification_footer, null, false);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt
index 8420c49..98bf0e6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt
@@ -40,6 +40,7 @@
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.shade.shadeTestUtil
 import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
 import com.android.systemui.statusbar.notification.collection.provider.visualStabilityProvider
@@ -179,6 +180,44 @@
     }
 
     @Test
+    fun pinnedHeadsUpStatuses_noHeadsUp() {
+        assertThat(underTest.hasPinnedHeadsUp()).isFalse()
+        assertThat(underTest.pinnedHeadsUpStatus()).isEqualTo(PinnedStatus.NotPinned)
+    }
+
+    @Test
+    fun pinnedHeadsUpStatuses_pinnedBySystem() {
+        val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+        entry.row = testHelper.createRow()
+        underTest.showNotification(entry, isPinnedByUser = false)
+
+        assertThat(underTest.hasPinnedHeadsUp()).isTrue()
+        assertThat(underTest.pinnedHeadsUpStatus()).isEqualTo(PinnedStatus.PinnedBySystem)
+    }
+
+    @Test
+    @DisableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun pinnedHeadsUpStatuses_pinnedByUser_butFlagOff_returnsNotPinned() {
+        val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+        entry.row = testHelper.createRow()
+        underTest.showNotification(entry, isPinnedByUser = true)
+
+        assertThat(underTest.hasPinnedHeadsUp()).isFalse()
+        assertThat(underTest.pinnedHeadsUpStatus()).isEqualTo(PinnedStatus.NotPinned)
+    }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun pinnedHeadsUpStatuses_pinnedByUser_flagOn() {
+        val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+        entry.row = testHelper.createRow()
+        underTest.showNotification(entry, isPinnedByUser = true)
+
+        assertThat(underTest.hasPinnedHeadsUp()).isTrue()
+        assertThat(underTest.pinnedHeadsUpStatus()).isEqualTo(PinnedStatus.PinnedByUser)
+    }
+
+    @Test
     @EnableFlags(NotificationThrottleHun.FLAG_NAME)
     fun testGetHeadsUpEntryList_includesAvalancheEntryList() {
         val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
@@ -199,10 +238,10 @@
     }
 
     @Test
-    fun testShowNotification_addsEntry() {
+    fun testShowNotification_notPinnedByUser_addsEntry() {
         val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
 
-        underTest.showNotification(entry)
+        underTest.showNotification(entry, isPinnedByUser = false)
 
         assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
         assertThat(underTest.hasNotifications()).isTrue()
@@ -210,20 +249,43 @@
     }
 
     @Test
-    fun testShowNotification_autoDismisses() {
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun testShowNotification_isPinnedByUser_addsEntry() {
         val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
 
-        underTest.showNotification(entry)
+        underTest.showNotification(entry, isPinnedByUser = true)
+
+        assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
+        assertThat(underTest.hasNotifications()).isTrue()
+        assertThat(underTest.getEntry(entry.key)).isEqualTo(entry)
+    }
+
+    @Test
+    fun testShowNotification_notPinnedByUser_autoDismisses() {
+        val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+
+        underTest.showNotification(entry, isPinnedByUser = false)
         systemClock.advanceTime((TEST_AUTO_DISMISS_TIME * 3 / 2).toLong())
 
         assertThat(underTest.isHeadsUpEntry(entry.key)).isFalse()
     }
 
     @Test
-    fun testRemoveNotification_removeDeferred() {
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun testShowNotification_isPinnedByUser_autoDismisses() {
         val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
 
-        underTest.showNotification(entry)
+        underTest.showNotification(entry, isPinnedByUser = true)
+        systemClock.advanceTime((TEST_AUTO_DISMISS_TIME * 3 / 2).toLong())
+
+        assertThat(underTest.isHeadsUpEntry(entry.key)).isFalse()
+    }
+
+    @Test
+    fun testRemoveNotification_notPinnedByUser_removeDeferred() {
+        val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+
+        underTest.showNotification(entry, isPinnedByUser = false)
 
         val removedImmediately =
             underTest.removeNotification(
@@ -236,10 +298,27 @@
     }
 
     @Test
-    fun testRemoveNotification_forceRemove() {
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun testRemoveNotification_isPinnedByUser_removeDeferred() {
         val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
 
-        underTest.showNotification(entry)
+        underTest.showNotification(entry, isPinnedByUser = true)
+
+        val removedImmediately =
+            underTest.removeNotification(
+                entry.key,
+                /* releaseImmediately= */ false,
+                "removeDeferred",
+            )
+        assertThat(removedImmediately).isFalse()
+        assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
+    }
+
+    @Test
+    fun testRemoveNotification_notPinnedByUser_forceRemove() {
+        val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+
+        underTest.showNotification(entry, isPinnedByUser = false)
 
         val removedImmediately =
             underTest.removeNotification(entry.key, /* releaseImmediately= */ true, "forceRemove")
@@ -248,11 +327,26 @@
     }
 
     @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun testRemoveNotification_isPinnedByUser_forceRemove() {
+        val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+
+        underTest.showNotification(entry, isPinnedByUser = true)
+
+        val removedImmediately =
+            underTest.removeNotification(entry.key, /* releaseImmediately= */ true, "forceRemove")
+        assertThat(removedImmediately).isTrue()
+        assertThat(underTest.isHeadsUpEntry(entry.key)).isFalse()
+    }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
     fun testReleaseAllImmediately() {
         for (i in 0 until 4) {
             val entry = HeadsUpManagerTestUtil.createEntry(i, mContext)
-            entry.row = mock<ExpandableNotificationRow>()
-            underTest.showNotification(entry)
+            entry.row = testHelper.createRow()
+            val isPinnedByUser = i % 2 == 0
+            underTest.showNotification(entry, isPinnedByUser)
         }
 
         underTest.releaseAllImmediately()
@@ -261,10 +355,21 @@
     }
 
     @Test
-    fun testCanRemoveImmediately_notShownLongEnough() {
+    fun testCanRemoveImmediately_notShownLongEnough_notPinnedByUser() {
         val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
 
-        underTest.showNotification(entry)
+        underTest.showNotification(entry, isPinnedByUser = false)
+
+        // The entry has just been added so we should not remove immediately.
+        assertThat(underTest.canRemoveImmediately(entry.key)).isFalse()
+    }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun testCanRemoveImmediately_notShownLongEnough_isPinnedByUser() {
+        val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+
+        underTest.showNotification(entry, isPinnedByUser = true)
 
         // The entry has just been added so we should not remove immediately.
         assertThat(underTest.canRemoveImmediately(entry.key)).isFalse()
@@ -365,17 +470,48 @@
     }
 
     @Test
-    fun testSnooze() {
+    fun testSnooze_notPinnedByUser() {
         val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
-        underTest.showNotification(entry)
+        underTest.showNotification(entry, isPinnedByUser = false)
+
         underTest.snooze()
+
         assertThat(underTest.isSnoozed(entry.sbn.packageName)).isTrue()
     }
 
     @Test
-    fun testSwipedOutNotification() {
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun testSnooze_isPinnedByUser() {
         val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
-        underTest.showNotification(entry)
+        underTest.showNotification(entry, isPinnedByUser = true)
+
+        underTest.snooze()
+
+        assertThat(underTest.isSnoozed(entry.sbn.packageName)).isTrue()
+    }
+
+    @Test
+    fun testSwipedOutNotification_notPinnedByUser() {
+        val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+        underTest.showNotification(entry, isPinnedByUser = false)
+        underTest.addSwipedOutNotification(entry.key)
+
+        // Remove should succeed because the notification is swiped out
+        val removedImmediately =
+            underTest.removeNotification(
+                entry.key,
+                /* releaseImmediately= */ false,
+                /* reason= */ "swipe out",
+            )
+        assertThat(removedImmediately).isTrue()
+        assertThat(underTest.isHeadsUpEntry(entry.key)).isFalse()
+    }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun testSwipedOutNotification_isPinnedByUser() {
+        val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+        underTest.showNotification(entry, isPinnedByUser = true)
         underTest.addSwipedOutNotification(entry.key)
 
         // Remove should succeed because the notification is swiped out
@@ -413,10 +549,24 @@
     }
 
     @Test
-    fun testExtendHeadsUp() {
+    fun testExtendHeadsUp_notPinnedByUser() {
         val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
-        underTest.showNotification(entry)
+        underTest.showNotification(entry, isPinnedByUser = false)
+
         underTest.extendHeadsUp()
+
+        systemClock.advanceTime(((TEST_AUTO_DISMISS_TIME + TEST_EXTENSION_TIME) / 2).toLong())
+        assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
+    }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun testExtendHeadsUp_isPinnedByUser() {
+        val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+        underTest.showNotification(entry, isPinnedByUser = true)
+
+        underTest.extendHeadsUp()
+
         systemClock.advanceTime(((TEST_AUTO_DISMISS_TIME + TEST_EXTENSION_TIME) / 2).toLong())
         assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
     }
@@ -465,7 +615,7 @@
         kosmos.visualStabilityProvider.isReorderingAllowed = true
 
         val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
-        underTest.showNotification(notifEntry)
+        underTest.showNotification(notifEntry, isPinnedByUser = false)
         assertThat(notifEntry.isSeenInShade).isFalse()
     }
 
@@ -604,7 +754,7 @@
                 HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id= */ 0, mContext)
 
             // Add notifEntry to ANM mAlertEntries map and make it NOT unpinned
-            underTest.showNotification(notifEntry)
+            underTest.showNotification(notifEntry, isPinnedByUser = false)
 
             val headsUpEntry = underTest.getHeadsUpEntry(notifEntry.key)
             headsUpEntry!!.mWasUnpinned = false
@@ -621,7 +771,7 @@
                 HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id= */ 0, mContext)
 
             // Add notifEntry to ANM mAlertEntries map and make it unpinned
-            underTest.showNotification(notifEntry)
+            underTest.showNotification(notifEntry, isPinnedByUser = false)
 
             val headsUpEntry = underTest.getHeadsUpEntry(notifEntry.key)
             headsUpEntry!!.mWasUnpinned = true
@@ -793,11 +943,11 @@
             )
 
         // Note: the standard way to show a notification would be calling showNotification rather
-        // than onAlertEntryAdded. However, in practice showNotification in effect adds
+        // than onEntryAdded. However, in practice showNotification in effect adds
         // the notification and then updates it; in order to not log twice, the entry needs
         // to have a functional ExpandableNotificationRow that can keep track of whether it's
         // pinned or not (via isRowPinned()). That feels like a lot to pull in to test this one bit.
-        underTest.onEntryAdded(entryToPin)
+        underTest.onEntryAdded(entryToPin, /* requestedPinnedStatus= */ PinnedStatus.PinnedBySystem)
 
         assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2)
         assertThat(AvalancheController.ThrottleEvent.AVALANCHE_THROTTLING_HUN_SHOWN.getId())
@@ -816,11 +966,11 @@
             )
 
         // Note: the standard way to show a notification would be calling showNotification rather
-        // than onAlertEntryAdded. However, in practice showNotification in effect adds
+        // than onEntryAdded. However, in practice showNotification in effect adds
         // the notification and then updates it; in order to not log twice, the entry needs
         // to have a functional ExpandableNotificationRow that can keep track of whether it's
         // pinned or not (via isRowPinned()). That feels like a lot to pull in to test this one bit.
-        underTest.onEntryAdded(entryToPin)
+        underTest.onEntryAdded(entryToPin, /* requestedPinnedStatus= */ PinnedStatus.PinnedBySystem)
 
         assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
         assertThat(HeadsUpManagerImpl.NotificationPeekEvent.NOTIFICATION_PEEK.id)
@@ -889,7 +1039,10 @@
         val flags: List<FlagsParameterization>
             get() = buildList {
                 addAll(
-                    FlagsParameterization.allCombinationsOf(NotificationThrottleHun.FLAG_NAME)
+                    FlagsParameterization.allCombinationsOf(
+                            NotificationThrottleHun.FLAG_NAME,
+                            StatusBarNotifChips.FLAG_NAME,
+                        )
                         .andSceneContainer()
                 )
             }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
index 46c360a..be20bc1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
@@ -225,16 +225,12 @@
             val displayId = 123
             darkIconRepository.darkState(displayId).value =
                 SysuiDarkIconDispatcher.DarkChange(emptyList(), 0f, 0xAABBCC)
-            val iconColorsLookup by collectLastValue(underTest.iconColors(displayId))
-            assertThat(iconColorsLookup).isNotNull()
-
-            val iconColors = iconColorsLookup?.iconColors(Rect())
+            val iconColors by collectLastValue(underTest.iconColors(displayId))
             assertThat(iconColors).isNotNull()
-            iconColors!!
 
-            assertThat(iconColors.tint).isEqualTo(0xAABBCC)
+            assertThat(iconColors!!.tint).isEqualTo(0xAABBCC)
 
-            val staticDrawableColor = iconColors.staticDrawableColor(Rect())
+            val staticDrawableColor = iconColors!!.staticDrawableColor(Rect())
 
             assertThat(staticDrawableColor).isEqualTo(0xAABBCC)
         }
@@ -245,8 +241,7 @@
             val displayId = 321
             darkIconRepository.darkState(displayId).value =
                 SysuiDarkIconDispatcher.DarkChange(listOf(Rect(0, 0, 5, 5)), 0f, 0xAABBCC)
-            val iconColorsLookup by collectLastValue(underTest.iconColors(displayId))
-            val iconColors = iconColorsLookup?.iconColors(Rect(1, 1, 4, 4))
+            val iconColors by collectLastValue(underTest.iconColors(displayId))
             val staticDrawableColor = iconColors?.staticDrawableColor(Rect(6, 6, 7, 7))
             assertThat(staticDrawableColor).isEqualTo(DarkIconDispatcher.DEFAULT_ICON_TINT)
         }
@@ -257,9 +252,9 @@
             val displayId = 987
             darkIconRepository.darkState(displayId).value =
                 SysuiDarkIconDispatcher.DarkChange(listOf(Rect(0, 0, 5, 5)), 0f, 0xAABBCC)
-            val iconColorsLookup by collectLastValue(underTest.iconColors(displayId))
-            val iconColors = iconColorsLookup?.iconColors(Rect(6, 6, 7, 7))
-            assertThat(iconColors).isNull()
+            val iconColors by collectLastValue(underTest.iconColors(displayId))
+            assertThat(iconColors!!.staticDrawableColor(Rect(6, 6, 7, 7)))
+                .isEqualTo(DarkIconDispatcher.DEFAULT_ICON_TINT)
         }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java
index af2789b..f7673da 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java
@@ -75,8 +75,8 @@
             return new CancellationSignal();
         });
 
-        mViewBinder.bindHeadsUpView(mEntry, null);
-        verify(mLogger).startBindingHun(eq(mEntry));
+        mViewBinder.bindHeadsUpView(mEntry, /* isPinnedByUser= */ false, null);
+        verify(mLogger).startBindingHun(mEntry, /* isPinnedByUser= */ false);
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
 
@@ -85,8 +85,8 @@
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
 
-        mViewBinder.bindHeadsUpView(mEntry, null);
-        verify(mLogger).startBindingHun(eq(mEntry));
+        mViewBinder.bindHeadsUpView(mEntry, /* isPinnedByUser= */ true, null);
+        verify(mLogger).startBindingHun(mEntry, /* isPinnedByUser= */ true);
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
 
@@ -116,8 +116,8 @@
             return new CancellationSignal();
         });
 
-        mViewBinder.bindHeadsUpView(mEntry, null);
-        verify(mLogger).startBindingHun(eq(mEntry));
+        mViewBinder.bindHeadsUpView(mEntry, /* isPinnedByUser= */ false, null);
+        verify(mLogger).startBindingHun(mEntry, /* isPinnedByUser= */ false);
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
 
@@ -140,8 +140,8 @@
             return new CancellationSignal();
         });
 
-        mViewBinder.bindHeadsUpView(mEntry, null);
-        verify(mLogger).startBindingHun(eq(mEntry));
+        mViewBinder.bindHeadsUpView(mEntry, /* isPinnedByUser= */ true, null);
+        verify(mLogger).startBindingHun(mEntry, /* isPinnedByUser= */ true);
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
 
@@ -167,8 +167,8 @@
             return new CancellationSignal();
         });
 
-        mViewBinder.bindHeadsUpView(mEntry, null);
-        verify(mLogger).startBindingHun(eq(mEntry));
+        mViewBinder.bindHeadsUpView(mEntry, /* isPinnedByUser= */ false, null);
+        verify(mLogger).startBindingHun(mEntry, /* isPinnedByUser= */ false);
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
index 9f98fd4..5a5ec90 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
@@ -21,9 +21,8 @@
 import android.view.View
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.settingslib.Utils
-import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.notification.FakeShadowView
 import com.android.systemui.statusbar.notification.NotificationUtils
 import com.android.systemui.statusbar.notification.SourceType
@@ -62,8 +61,8 @@
             } as T?
         }
 
-        mNormalColor = Utils.getColorAttrDefaultColor(mContext,
-                com.android.internal.R.attr.materialColorSurfaceContainerHigh)
+        mNormalColor =
+            mContext.getColor(com.android.internal.R.color.materialColorSurfaceContainerHigh)
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.kt
index a9afb06..f4c2545 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.kt
@@ -16,6 +16,7 @@
 package com.android.systemui.statusbar.phone
 
 import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
 import android.testing.TestableLooper
 import android.testing.TestableLooper.RunWithLooper
 import android.view.View
@@ -23,12 +24,15 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
 import com.android.systemui.kosmos.useUnconfinedTestDispatcher
 import com.android.systemui.plugins.fakeDarkIconDispatcher
 import com.android.systemui.plugins.statusbar.statusBarStateController
 import com.android.systemui.shade.ShadeHeadsUpTracker
 import com.android.systemui.shade.shadeViewController
 import com.android.systemui.statusbar.HeadsUpStatusBarView
+import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
 import com.android.systemui.statusbar.commandQueue
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationIconInteractor
@@ -114,65 +118,172 @@
     }
 
     @Test
-    fun testShowinEntryUpdated() {
+    fun showingEntryUpdated_whenPinnedBySystem() {
         row.setPinnedStatus(PinnedStatus.PinnedBySystem)
-        whenever(headsUpManager.hasPinnedHeadsUp()).thenReturn(true)
-        whenever(headsUpManager.getTopEntry()).thenReturn(entry)
+        setHeadsUpNotifOnManager(entry)
         underTest.onHeadsUpPinned(entry)
+
         assertThat(headsUpStatusBarView.showingEntry).isEqualTo(row.entry)
 
         row.setPinnedStatus(PinnedStatus.NotPinned)
-        whenever(headsUpManager.hasPinnedHeadsUp()).thenReturn(false)
+        setHeadsUpNotifOnManager(null)
         underTest.onHeadsUpUnPinned(entry)
+
         assertThat(headsUpStatusBarView.showingEntry).isNull()
     }
 
     @Test
-    fun testPinnedStatusUpdated() {
+    @DisableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun showingEntryUpdated_whenPinnedByUser_andFlagOff() {
+        row.setPinnedStatus(PinnedStatus.PinnedByUser)
+        setHeadsUpNotifOnManager(entry)
+        underTest.onHeadsUpPinned(entry)
+
+        assertThat(headsUpStatusBarView.showingEntry).isEqualTo(row.entry)
+    }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun showingEntryNotUpdated_whenPinnedByUser_andFlagOn() {
+        // WHEN the HUN was pinned by the user
+        row.setPinnedStatus(PinnedStatus.PinnedByUser)
+        setHeadsUpNotifOnManager(entry)
+        underTest.onHeadsUpPinned(entry)
+
+        // THEN we don't show the HUN status bar view
+        assertThat(headsUpStatusBarView.showingEntry).isNull()
+    }
+
+    @Test
+    fun pinnedStatusUpdatedToSystem_whenPinnedBySystem() {
         row.setPinnedStatus(PinnedStatus.PinnedBySystem)
-        whenever(headsUpManager.hasPinnedHeadsUp()).thenReturn(true)
-        whenever(headsUpManager.getTopEntry()).thenReturn(entry)
+        setHeadsUpNotifOnManager(entry)
         underTest.onHeadsUpPinned(entry)
         assertThat(underTest.pinnedStatus).isEqualTo(PinnedStatus.PinnedBySystem)
 
         row.setPinnedStatus(PinnedStatus.NotPinned)
-        whenever(headsUpManager.hasPinnedHeadsUp()).thenReturn(false)
+        setHeadsUpNotifOnManager(null)
         underTest.onHeadsUpUnPinned(entry)
         assertThat(underTest.pinnedStatus).isEqualTo(PinnedStatus.NotPinned)
     }
 
     @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun pinnedStatusUpdatedToNotPinned_whenPinnedByUser_andFlagOn() {
+        row.setPinnedStatus(PinnedStatus.PinnedByUser)
+        setHeadsUpNotifOnManager(entry)
+        underTest.onHeadsUpPinned(entry)
+
+        // It's unintuitive that the pinnedStatus wouldn't match the status on the notification.
+        // Explanation: HeadsUpAppearanceController#updateTopEntry doesn't do anything if
+        // HeadsUpManager.pinnedHeadsUpStatus != PinnedBySystem. So when we're PinnedByUser,
+        // HeadsUpAppearanceController early-returns before even updating the pinned status.
+        assertThat(underTest.pinnedStatus).isEqualTo(PinnedStatus.NotPinned)
+    }
+
+    @Test
+    fun isolatedIconSet_whenPinnedBySystem() =
+        kosmos.runTest {
+            val latestIsolatedIcon by
+                collectLastValue(kosmos.headsUpNotificationIconInteractor.isolatedNotification)
+
+            row.setPinnedStatus(PinnedStatus.PinnedBySystem)
+            setHeadsUpNotifOnManager(entry)
+            underTest.onHeadsUpPinned(entry)
+
+            assertThat(latestIsolatedIcon).isEqualTo(entry.key)
+
+            row.setPinnedStatus(PinnedStatus.NotPinned)
+            setHeadsUpNotifOnManager(null)
+            underTest.onHeadsUpUnPinned(entry)
+
+            assertThat(latestIsolatedIcon).isNull()
+        }
+
+    @Test
+    @DisableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun isolatedIconSet_whenPinnedByUser_andFlagOff() =
+        kosmos.runTest {
+            val latestIsolatedIcon by
+                collectLastValue(kosmos.headsUpNotificationIconInteractor.isolatedNotification)
+
+            row.setPinnedStatus(PinnedStatus.PinnedByUser)
+            setHeadsUpNotifOnManager(entry)
+            underTest.onHeadsUpPinned(entry)
+
+            assertThat(latestIsolatedIcon).isEqualTo(entry.key)
+        }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun isolatedIconNotSet_whenPinnedByUser_andFlagOn() =
+        kosmos.runTest {
+            val latestIsolatedIcon by
+                collectLastValue(kosmos.headsUpNotificationIconInteractor.isolatedNotification)
+
+            row.setPinnedStatus(PinnedStatus.PinnedByUser)
+            setHeadsUpNotifOnManager(entry)
+            underTest.onHeadsUpPinned(entry)
+
+            assertThat(latestIsolatedIcon).isNull()
+        }
+
+    @Test
     @DisableFlags(AsyncGroupHeaderViewInflation.FLAG_NAME)
     fun testHeaderUpdated() {
         row.setPinnedStatus(PinnedStatus.PinnedBySystem)
-        whenever(headsUpManager.hasPinnedHeadsUp()).thenReturn(true)
-        whenever(headsUpManager.getTopEntry()).thenReturn(entry)
+        setHeadsUpNotifOnManager(entry)
         underTest.onHeadsUpPinned(entry)
         assertThat(row.headerVisibleAmount).isEqualTo(0.0f)
 
         row.setPinnedStatus(PinnedStatus.NotPinned)
-        whenever(headsUpManager.hasPinnedHeadsUp()).thenReturn(false)
+        setHeadsUpNotifOnManager(null)
         underTest.onHeadsUpUnPinned(entry)
         assertThat(row.headerVisibleAmount).isEqualTo(1.0f)
     }
 
     @Test
-    fun testOperatorNameViewUpdated() {
+    fun operatorNameViewUpdated_whenPinnedBySystem() {
         underTest.setAnimationsEnabled(false)
 
         row.setPinnedStatus(PinnedStatus.PinnedBySystem)
-        whenever(headsUpManager.hasPinnedHeadsUp()).thenReturn(true)
-        whenever(headsUpManager.getTopEntry()).thenReturn(entry)
+        setHeadsUpNotifOnManager(entry)
         underTest.onHeadsUpPinned(entry)
         assertThat(operatorNameView.visibility).isEqualTo(View.INVISIBLE)
 
         row.setPinnedStatus(PinnedStatus.NotPinned)
-        whenever(headsUpManager.hasPinnedHeadsUp()).thenReturn(false)
+        setHeadsUpNotifOnManager(null)
         underTest.onHeadsUpUnPinned(entry)
         assertThat(operatorNameView.visibility).isEqualTo(View.VISIBLE)
     }
 
     @Test
+    @DisableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun operatorNameViewUpdated_whenPinnedByUser_andFlagOff() {
+        underTest.setAnimationsEnabled(false)
+
+        row.setPinnedStatus(PinnedStatus.PinnedByUser)
+        setHeadsUpNotifOnManager(entry)
+        underTest.onHeadsUpPinned(entry)
+
+        assertThat(operatorNameView.visibility).isEqualTo(View.INVISIBLE)
+    }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun operatorNameViewNotUpdated_whenPinnedByUser_andFlagOn() {
+        underTest.setAnimationsEnabled(false)
+
+        // WHEN the row was pinned by the user
+        row.setPinnedStatus(PinnedStatus.PinnedByUser)
+        setHeadsUpNotifOnManager(entry)
+        underTest.onHeadsUpPinned(entry)
+
+        // THEN we don't need to hide the operator name view
+        assertThat(operatorNameView.visibility).isEqualTo(View.VISIBLE)
+    }
+
+    @Test
     fun constructor_animationValuesUpdated() {
         val appearFraction = .75f
         val expandedHeight = 400f
@@ -276,4 +387,16 @@
 
         verify(phoneStatusBarTransitions).onHeadsUpStateChanged(false)
     }
+
+    private fun setHeadsUpNotifOnManager(entry: NotificationEntry?) {
+        if (entry != null) {
+            whenever(headsUpManager.hasPinnedHeadsUp()).thenReturn(true)
+            whenever(headsUpManager.pinnedHeadsUpStatus()).thenReturn(entry.pinnedStatus)
+            whenever(headsUpManager.getTopEntry()).thenReturn(entry)
+        } else {
+            whenever(headsUpManager.hasPinnedHeadsUp()).thenReturn(false)
+            whenever(headsUpManager.pinnedHeadsUpStatus()).thenReturn(PinnedStatus.NotPinned)
+            whenever(headsUpManager.getTopEntry()).thenReturn(null)
+        }
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
deleted file mode 100644
index 41782a1..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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 static android.view.Display.DEFAULT_DISPLAY;
-
-import static com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.BUBBLE;
-import static com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PEEK;
-import static com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PULSE;
-
-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.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.app.StatusBarManager;
-import android.platform.test.annotations.DisableFlags;
-import android.platform.test.annotations.EnableFlags;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.InitController;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.power.domain.interactor.PowerInteractor;
-import com.android.systemui.settings.FakeDisplayTracker;
-import com.android.systemui.shade.NotificationShadeWindowView;
-import com.android.systemui.shade.QuickSettingsController;
-import com.android.systemui.shade.ShadeController;
-import com.android.systemui.shade.ShadeViewController;
-import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.LockscreenShadeTransitionController;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.NotificationMediaManager;
-import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.notification.DynamicPrivacyController;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
-import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
-import com.android.systemui.statusbar.notification.domain.interactor.NotificationAlertsInteractor;
-import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor;
-import com.android.systemui.statusbar.notification.interruption.VisualInterruptionCondition;
-import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider;
-import com.android.systemui.statusbar.notification.interruption.VisualInterruptionFilter;
-import com.android.systemui.statusbar.notification.interruption.VisualInterruptionRefactor;
-import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType;
-import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
-import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-
-import java.util.List;
-import java.util.Set;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-@RunWithLooper()
-public class StatusBarNotificationPresenterTest extends SysuiTestCase {
-    private StatusBarNotificationPresenter mStatusBarNotificationPresenter;
-    private final VisualInterruptionDecisionProvider mVisualInterruptionDecisionProvider =
-            mock(VisualInterruptionDecisionProvider.class);
-    private NotificationInterruptSuppressor mInterruptSuppressor;
-    private VisualInterruptionCondition mAlertsDisabledCondition;
-    private VisualInterruptionCondition mVrModeCondition;
-    private VisualInterruptionFilter mNeedsRedactionFilter;
-    private VisualInterruptionCondition mPanelsDisabledCondition;
-    private CommandQueue mCommandQueue;
-    private final ShadeController mShadeController = mock(ShadeController.class);
-    private final NotificationAlertsInteractor mNotificationAlertsInteractor =
-            mock(NotificationAlertsInteractor.class);
-    private final KeyguardStateController mKeyguardStateController =
-            mock(KeyguardStateController.class);
-
-    @Before
-    public void setup() {
-        mCommandQueue = new CommandQueue(mContext, new FakeDisplayTracker(mContext));
-        mDependency.injectTestDependency(StatusBarStateController.class,
-                mock(SysuiStatusBarStateController.class));
-        mDependency.injectTestDependency(ShadeController.class, mShadeController);
-        mDependency.injectMockDependency(NotificationRemoteInputManager.Callback.class);
-        mDependency.injectMockDependency(NotificationShadeWindowController.class);
-
-        when(mNotificationAlertsInteractor.areNotificationAlertsEnabled()).thenReturn(true);
-
-        createPresenter();
-        if (VisualInterruptionRefactor.isEnabled()) {
-            verifyAndCaptureSuppressors();
-        } else {
-            verifyAndCaptureLegacySuppressor();
-        }
-    }
-
-    @Test
-    @DisableFlags(VisualInterruptionRefactor.FLAG_NAME)
-    public void testInit_refactorDisabled() {
-        assertFalse(VisualInterruptionRefactor.isEnabled());
-        assertNull(mAlertsDisabledCondition);
-        assertNull(mVrModeCondition);
-        assertNull(mNeedsRedactionFilter);
-        assertNull(mPanelsDisabledCondition);
-        assertNotNull(mInterruptSuppressor);
-    }
-
-    @Test
-    @EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
-    public void testInit_refactorEnabled() {
-        assertTrue(VisualInterruptionRefactor.isEnabled());
-        assertNotNull(mAlertsDisabledCondition);
-        assertNotNull(mVrModeCondition);
-        assertNotNull(mNeedsRedactionFilter);
-        assertNotNull(mPanelsDisabledCondition);
-        assertNull(mInterruptSuppressor);
-    }
-
-    @Test
-    @DisableFlags(VisualInterruptionRefactor.FLAG_NAME)
-    public void testNoSuppressHeadsUp_default_refactorDisabled() {
-        assertFalse(mInterruptSuppressor.suppressAwakeHeadsUp(createNotificationEntry()));
-    }
-
-    @Test
-    @EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
-    public void testNoSuppressHeadsUp_default_refactorEnabled() {
-        assertFalse(mAlertsDisabledCondition.shouldSuppress());
-        assertFalse(mVrModeCondition.shouldSuppress());
-        assertFalse(mNeedsRedactionFilter.shouldSuppress(createNotificationEntry()));
-        assertFalse(mAlertsDisabledCondition.shouldSuppress());
-    }
-
-    @Test
-    @DisableFlags(VisualInterruptionRefactor.FLAG_NAME)
-    public void testSuppressHeadsUp_disabledStatusBar_refactorDisabled() {
-        mCommandQueue.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_EXPAND, 0,
-                false /* animate */);
-        TestableLooper.get(this).processAllMessages();
-
-        assertTrue("The panel should suppress heads up while disabled",
-                mInterruptSuppressor.suppressAwakeHeadsUp(createNotificationEntry()));
-    }
-
-    @Test
-    @EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
-    public void testSuppressHeadsUp_disabledStatusBar_refactorEnabled() {
-        mCommandQueue.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_EXPAND, 0,
-                false /* animate */);
-        TestableLooper.get(this).processAllMessages();
-
-        assertTrue("The panel should suppress heads up while disabled",
-                mPanelsDisabledCondition.shouldSuppress());
-    }
-
-    @Test
-    @DisableFlags(VisualInterruptionRefactor.FLAG_NAME)
-    public void testSuppressHeadsUp_disabledNotificationShade_refactorDisabled() {
-        mCommandQueue.disable(DEFAULT_DISPLAY, 0, StatusBarManager.DISABLE2_NOTIFICATION_SHADE,
-                false /* animate */);
-        TestableLooper.get(this).processAllMessages();
-
-        assertTrue("The panel should suppress interruptions while notification shade disabled",
-                mInterruptSuppressor.suppressAwakeHeadsUp(createNotificationEntry()));
-    }
-
-    @Test
-    @EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
-    public void testSuppressHeadsUp_disabledNotificationShade_refactorEnabled() {
-        mCommandQueue.disable(DEFAULT_DISPLAY, 0, StatusBarManager.DISABLE2_NOTIFICATION_SHADE,
-                false /* animate */);
-        TestableLooper.get(this).processAllMessages();
-
-        assertTrue("The panel should suppress interruptions while notification shade disabled",
-                mPanelsDisabledCondition.shouldSuppress());
-    }
-
-    @Test
-    @EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
-    public void testPanelsDisabledConditionSuppressesPeek() {
-        final Set<VisualInterruptionType> types = mPanelsDisabledCondition.getTypes();
-        assertTrue(types.contains(PEEK));
-        assertFalse(types.contains(PULSE));
-        assertFalse(types.contains(BUBBLE));
-    }
-
-    @Test
-    @DisableFlags(VisualInterruptionRefactor.FLAG_NAME)
-    public void testNoSuppressHeadsUp_FSI_nonOccludedKeyguard_refactorDisabled() {
-        when(mKeyguardStateController.isShowing()).thenReturn(true);
-        when(mKeyguardStateController.isOccluded()).thenReturn(false);
-
-        assertFalse(mInterruptSuppressor.suppressAwakeHeadsUp(createFsiNotificationEntry()));
-    }
-
-    @Test
-    @EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
-    public void testNoSuppressHeadsUp_FSI_nonOccludedKeyguard_refactorEnabled() {
-        when(mKeyguardStateController.isShowing()).thenReturn(true);
-        when(mKeyguardStateController.isOccluded()).thenReturn(false);
-
-        assertFalse(mNeedsRedactionFilter.shouldSuppress(createFsiNotificationEntry()));
-
-        final Set<VisualInterruptionType> types = mNeedsRedactionFilter.getTypes();
-        assertTrue(types.contains(PEEK));
-        assertFalse(types.contains(PULSE));
-        assertFalse(types.contains(BUBBLE));
-    }
-
-    @Test
-    @DisableFlags(VisualInterruptionRefactor.FLAG_NAME)
-    public void testSuppressInterruptions_vrMode_refactorDisabled() {
-        mStatusBarNotificationPresenter.mVrMode = true;
-
-        assertTrue("Vr mode should suppress interruptions",
-                mInterruptSuppressor.suppressAwakeInterruptions(createNotificationEntry()));
-    }
-
-    @Test
-    @EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
-    public void testSuppressInterruptions_vrMode_refactorEnabled() {
-        mStatusBarNotificationPresenter.mVrMode = true;
-
-        assertTrue("Vr mode should suppress interruptions", mVrModeCondition.shouldSuppress());
-
-        final Set<VisualInterruptionType> types = mVrModeCondition.getTypes();
-        assertTrue(types.contains(PEEK));
-        assertFalse(types.contains(PULSE));
-        assertTrue(types.contains(BUBBLE));
-    }
-
-    @Test
-    @DisableFlags(VisualInterruptionRefactor.FLAG_NAME)
-    public void testSuppressInterruptions_statusBarAlertsDisabled_refactorDisabled() {
-        when(mNotificationAlertsInteractor.areNotificationAlertsEnabled()).thenReturn(false);
-
-        assertTrue("When alerts aren't enabled, interruptions are suppressed",
-                mInterruptSuppressor.suppressInterruptions(createNotificationEntry()));
-    }
-
-    @Test
-    @EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
-    public void testSuppressInterruptions_statusBarAlertsDisabled_refactorEnabled() {
-        when(mNotificationAlertsInteractor.areNotificationAlertsEnabled()).thenReturn(false);
-
-        assertTrue("When alerts aren't enabled, interruptions are suppressed",
-                mAlertsDisabledCondition.shouldSuppress());
-
-        final Set<VisualInterruptionType> types = mAlertsDisabledCondition.getTypes();
-        assertTrue(types.contains(PEEK));
-        assertTrue(types.contains(PULSE));
-        assertTrue(types.contains(BUBBLE));
-    }
-
-    private void createPresenter() {
-        final ShadeViewController shadeViewController = mock(ShadeViewController.class);
-
-        final NotificationShadeWindowView notificationShadeWindowView =
-                mock(NotificationShadeWindowView.class);
-        when(notificationShadeWindowView.getResources()).thenReturn(mContext.getResources());
-
-        NotificationStackScrollLayoutController stackScrollLayoutController =
-                mock(NotificationStackScrollLayoutController.class);
-        when(stackScrollLayoutController.getView()).thenReturn(
-                mock(NotificationStackScrollLayout.class));
-
-        final InitController initController = new InitController();
-
-        mStatusBarNotificationPresenter = new StatusBarNotificationPresenter(
-                mContext,
-                shadeViewController,
-                mock(PanelExpansionInteractor.class),
-                mock(QuickSettingsController.class),
-                mock(HeadsUpManager.class),
-                notificationShadeWindowView,
-                mock(ActivityStarter.class),
-                stackScrollLayoutController,
-                mock(DozeScrimController.class),
-                mock(NotificationShadeWindowController.class),
-                mock(DynamicPrivacyController.class),
-                mKeyguardStateController,
-                mNotificationAlertsInteractor,
-                mock(LockscreenShadeTransitionController.class),
-                mock(PowerInteractor.class),
-                mCommandQueue,
-                mock(NotificationLockscreenUserManager.class),
-                mock(SysuiStatusBarStateController.class),
-                mock(NotifShadeEventSource.class),
-                mock(NotificationMediaManager.class),
-                mock(NotificationGutsManager.class),
-                initController,
-                mVisualInterruptionDecisionProvider,
-                mock(NotificationRemoteInputManager.class),
-                mock(NotificationRemoteInputManager.Callback.class),
-                mock(NotificationListContainer.class));
-
-        initController.executePostInitTasks();
-    }
-
-    private void verifyAndCaptureSuppressors() {
-        mInterruptSuppressor = null;
-
-        final ArgumentCaptor<VisualInterruptionCondition> conditionCaptor =
-                ArgumentCaptor.forClass(VisualInterruptionCondition.class);
-        verify(mVisualInterruptionDecisionProvider, times(3)).addCondition(
-                conditionCaptor.capture());
-        final List<VisualInterruptionCondition> conditions = conditionCaptor.getAllValues();
-        mAlertsDisabledCondition = conditions.get(0);
-        mVrModeCondition = conditions.get(1);
-        mPanelsDisabledCondition = conditions.get(2);
-
-        final ArgumentCaptor<VisualInterruptionFilter> needsRedactionFilterCaptor =
-                ArgumentCaptor.forClass(VisualInterruptionFilter.class);
-        verify(mVisualInterruptionDecisionProvider).addFilter(needsRedactionFilterCaptor.capture());
-        mNeedsRedactionFilter = needsRedactionFilterCaptor.getValue();
-    }
-
-    private void verifyAndCaptureLegacySuppressor() {
-        mAlertsDisabledCondition = null;
-        mVrModeCondition = null;
-        mNeedsRedactionFilter = null;
-        mPanelsDisabledCondition = null;
-
-        final ArgumentCaptor<NotificationInterruptSuppressor> suppressorCaptor =
-                ArgumentCaptor.forClass(NotificationInterruptSuppressor.class);
-        verify(mVisualInterruptionDecisionProvider).addLegacySuppressor(suppressorCaptor.capture());
-        mInterruptSuppressor = suppressorCaptor.getValue();
-    }
-
-    private NotificationEntry createNotificationEntry() {
-        return new NotificationEntryBuilder()
-                .setPkg("a")
-                .setOpPkg("a")
-                .setTag("a")
-                .setNotification(new Notification.Builder(getContext(), "a").build())
-                .build();
-    }
-
-    private NotificationEntry createFsiNotificationEntry() {
-        final Notification notification = new Notification.Builder(getContext(), "a")
-                .setFullScreenIntent(mock(PendingIntent.class), true)
-                .build();
-
-        return new NotificationEntryBuilder()
-                .setPkg("a")
-                .setOpPkg("a")
-                .setTag("a")
-                .setNotification(notification)
-                .build();
-    }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.kt
new file mode 100644
index 0000000..c347347
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.kt
@@ -0,0 +1,454 @@
+/*
+ * 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 android.app.Notification
+import android.app.Notification.Builder
+import android.app.StatusBarManager
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.testing.TestableLooper
+import android.testing.TestableLooper.RunWithLooper
+import android.view.Display.DEFAULT_DISPLAY
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.InitController
+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.deviceentry.domain.interactor.deviceUnlockedInteractor
+import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.plugins.activityStarter
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.settings.FakeDisplayTracker
+import com.android.systemui.shade.NotificationShadeWindowView
+import com.android.systemui.shade.ShadeViewController
+import com.android.systemui.shade.domain.interactor.panelExpansionInteractor
+import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.lockscreenShadeTransitionController
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.domain.interactor.notificationAlertsInteractor
+import com.android.systemui.statusbar.notification.dynamicPrivacyController
+import com.android.systemui.statusbar.notification.headsup.headsUpManager
+import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor
+import com.android.systemui.statusbar.notification.interruption.VisualInterruptionCondition
+import com.android.systemui.statusbar.notification.interruption.VisualInterruptionFilter
+import com.android.systemui.statusbar.notification.interruption.VisualInterruptionRefactor
+import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.stack.notificationStackScrollLayoutController
+import com.android.systemui.statusbar.notification.visualInterruptionDecisionProvider
+import com.android.systemui.statusbar.notificationLockscreenUserManager
+import com.android.systemui.statusbar.notificationRemoteInputManager
+import com.android.systemui.statusbar.notificationShadeWindowController
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.statusbar.policy.keyguardStateController
+import com.android.systemui.statusbar.sysuiStatusBarStateController
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@RunWithLooper
+class StatusBarNotificationPresenterTest : SysuiTestCase() {
+    private lateinit var kosmos: Kosmos
+
+    private var interruptSuppressor: NotificationInterruptSuppressor? = null
+    private var alertsDisabledCondition: VisualInterruptionCondition? = null
+    private var vrModeCondition: VisualInterruptionCondition? = null
+    private var needsRedactionFilter: VisualInterruptionFilter? = null
+    private var panelsDisabledCondition: VisualInterruptionCondition? = null
+
+    private val commandQueue: CommandQueue = CommandQueue(mContext, FakeDisplayTracker(mContext))
+    private val keyguardStateController: KeyguardStateController
+        get() = kosmos.keyguardStateController
+
+    private val notificationAlertsInteractor
+        get() = kosmos.notificationAlertsInteractor
+
+    private val visualInterruptionDecisionProvider
+        get() = kosmos.visualInterruptionDecisionProvider
+
+    private lateinit var underTest: StatusBarNotificationPresenter
+
+    @Before
+    fun setup() {
+        kosmos =
+            testKosmos().apply {
+                whenever(notificationAlertsInteractor.areNotificationAlertsEnabled())
+                    .thenReturn(true)
+                whenever(notificationStackScrollLayoutController.expandHelperCallback)
+                    .thenReturn(mock())
+                lockscreenShadeTransitionController.setStackScroller(
+                    notificationStackScrollLayoutController
+                )
+                lockscreenShadeTransitionController.centralSurfaces = mock()
+            }
+
+        underTest = createPresenter()
+        if (VisualInterruptionRefactor.isEnabled) {
+            verifyAndCaptureSuppressors()
+        } else {
+            verifyAndCaptureLegacySuppressor()
+        }
+    }
+
+    @Test
+    @DisableFlags(VisualInterruptionRefactor.FLAG_NAME)
+    fun testInit_refactorDisabled() {
+        assertThat(VisualInterruptionRefactor.isEnabled).isFalse()
+        assertThat(alertsDisabledCondition).isNull()
+        assertThat(vrModeCondition).isNull()
+        assertThat(needsRedactionFilter).isNull()
+        assertThat(panelsDisabledCondition).isNull()
+        assertThat(interruptSuppressor).isNotNull()
+    }
+
+    @Test
+    @EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
+    fun testInit_refactorEnabled() {
+        assertThat(VisualInterruptionRefactor.isEnabled).isTrue()
+        assertThat(alertsDisabledCondition).isNotNull()
+        assertThat(vrModeCondition).isNotNull()
+        assertThat(needsRedactionFilter).isNotNull()
+        assertThat(panelsDisabledCondition).isNotNull()
+        assertThat(interruptSuppressor).isNull()
+    }
+
+    @Test
+    @DisableFlags(VisualInterruptionRefactor.FLAG_NAME)
+    fun testNoSuppressHeadsUp_default_refactorDisabled() {
+        assertThat(interruptSuppressor!!.suppressAwakeHeadsUp(createNotificationEntry())).isFalse()
+    }
+
+    @Test
+    @EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
+    fun testNoSuppressHeadsUp_default_refactorEnabled() {
+        assertThat(alertsDisabledCondition!!.shouldSuppress()).isFalse()
+        assertThat(vrModeCondition!!.shouldSuppress()).isFalse()
+        assertThat(needsRedactionFilter!!.shouldSuppress(createNotificationEntry())).isFalse()
+        assertThat(alertsDisabledCondition!!.shouldSuppress()).isFalse()
+    }
+
+    @Test
+    @DisableFlags(VisualInterruptionRefactor.FLAG_NAME)
+    fun testSuppressHeadsUp_disabledStatusBar_refactorDisabled() {
+        commandQueue.disable(
+            DEFAULT_DISPLAY,
+            StatusBarManager.DISABLE_EXPAND,
+            0,
+            false, /* animate */
+        )
+        TestableLooper.get(this).processAllMessages()
+
+        assertWithMessage("The panel should suppress heads up while disabled")
+            .that(interruptSuppressor!!.suppressAwakeHeadsUp(createNotificationEntry()))
+            .isTrue()
+    }
+
+    @Test
+    @EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
+    fun testSuppressHeadsUp_disabledStatusBar_refactorEnabled() {
+        commandQueue.disable(
+            DEFAULT_DISPLAY,
+            StatusBarManager.DISABLE_EXPAND,
+            0,
+            false, /* animate */
+        )
+        TestableLooper.get(this).processAllMessages()
+
+        assertWithMessage("The panel should suppress heads up while disabled")
+            .that(panelsDisabledCondition!!.shouldSuppress())
+            .isTrue()
+    }
+
+    @Test
+    @DisableFlags(VisualInterruptionRefactor.FLAG_NAME)
+    fun testSuppressHeadsUp_disabledNotificationShade_refactorDisabled() {
+        commandQueue.disable(
+            DEFAULT_DISPLAY,
+            0,
+            StatusBarManager.DISABLE2_NOTIFICATION_SHADE,
+            false, /* animate */
+        )
+        TestableLooper.get(this).processAllMessages()
+
+        assertWithMessage(
+                "The panel should suppress interruptions while notification shade disabled"
+            )
+            .that(interruptSuppressor!!.suppressAwakeHeadsUp(createNotificationEntry()))
+            .isTrue()
+    }
+
+    @Test
+    @EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
+    fun testSuppressHeadsUp_disabledNotificationShade_refactorEnabled() {
+        commandQueue.disable(
+            DEFAULT_DISPLAY,
+            0,
+            StatusBarManager.DISABLE2_NOTIFICATION_SHADE,
+            false, /* animate */
+        )
+        TestableLooper.get(this).processAllMessages()
+
+        assertWithMessage(
+                "The panel should suppress interruptions while notification shade disabled"
+            )
+            .that(panelsDisabledCondition!!.shouldSuppress())
+            .isTrue()
+    }
+
+    @Test
+    @EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
+    fun testPanelsDisabledConditionSuppressesPeek() {
+        val types: Set<VisualInterruptionType> = panelsDisabledCondition!!.types
+        assertThat(types).contains(VisualInterruptionType.PEEK)
+        assertThat(types)
+            .containsNoneOf(VisualInterruptionType.BUBBLE, VisualInterruptionType.PULSE)
+    }
+
+    @Test
+    @DisableFlags(VisualInterruptionRefactor.FLAG_NAME)
+    fun testNoSuppressHeadsUp_FSI_nonOccludedKeyguard_refactorDisabled() {
+        whenever(keyguardStateController.isShowing()).thenReturn(true)
+        whenever(keyguardStateController.isOccluded()).thenReturn(false)
+
+        assertThat(interruptSuppressor!!.suppressAwakeHeadsUp(createFsiNotificationEntry()))
+            .isFalse()
+    }
+
+    @Test
+    @EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
+    fun testNoSuppressHeadsUp_FSI_nonOccludedKeyguard_refactorEnabled() {
+        whenever(keyguardStateController.isShowing()).thenReturn(true)
+        whenever(keyguardStateController.isOccluded()).thenReturn(false)
+
+        assertThat(needsRedactionFilter!!.shouldSuppress(createFsiNotificationEntry())).isFalse()
+
+        val types: Set<VisualInterruptionType> = needsRedactionFilter!!.types
+        assertThat(types).contains(VisualInterruptionType.PEEK)
+        assertThat(types)
+            .containsNoneOf(VisualInterruptionType.BUBBLE, VisualInterruptionType.PULSE)
+    }
+
+    @Test
+    @DisableFlags(VisualInterruptionRefactor.FLAG_NAME)
+    fun testSuppressInterruptions_vrMode_refactorDisabled() {
+        underTest.mVrMode = true
+
+        assertWithMessage("Vr mode should suppress interruptions")
+            .that(interruptSuppressor!!.suppressAwakeInterruptions(createNotificationEntry()))
+            .isTrue()
+    }
+
+    @Test
+    @EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
+    fun testSuppressInterruptions_vrMode_refactorEnabled() {
+        underTest.mVrMode = true
+
+        assertWithMessage("Vr mode should suppress interruptions")
+            .that(vrModeCondition!!.shouldSuppress())
+            .isTrue()
+
+        val types: Set<VisualInterruptionType> = vrModeCondition!!.types
+        assertThat(types).contains(VisualInterruptionType.PEEK)
+        assertThat(types).doesNotContain(VisualInterruptionType.PULSE)
+        assertThat(types).contains(VisualInterruptionType.BUBBLE)
+    }
+
+    @Test
+    @DisableFlags(VisualInterruptionRefactor.FLAG_NAME)
+    fun testSuppressInterruptions_statusBarAlertsDisabled_refactorDisabled() {
+        whenever(notificationAlertsInteractor.areNotificationAlertsEnabled()).thenReturn(false)
+
+        assertWithMessage("When alerts aren't enabled, interruptions are suppressed")
+            .that(interruptSuppressor!!.suppressInterruptions(createNotificationEntry()))
+            .isTrue()
+    }
+
+    @Test
+    @EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
+    fun testSuppressInterruptions_statusBarAlertsDisabled_refactorEnabled() {
+        whenever(notificationAlertsInteractor.areNotificationAlertsEnabled()).thenReturn(false)
+
+        assertWithMessage("When alerts aren't enabled, interruptions are suppressed")
+            .that(alertsDisabledCondition!!.shouldSuppress())
+            .isTrue()
+
+        val types: Set<VisualInterruptionType> = alertsDisabledCondition!!.types
+        assertThat(types).contains(VisualInterruptionType.PEEK)
+        assertThat(types).contains(VisualInterruptionType.PULSE)
+        assertThat(types).contains(VisualInterruptionType.BUBBLE)
+    }
+
+    @Test
+    @EnableSceneContainer
+    fun testExpandSensitiveNotification_onLockScreen_opensShade() =
+        kosmos.runTest {
+            // Given we are on the keyguard
+            kosmos.sysuiStatusBarStateController.state = StatusBarState.KEYGUARD
+            // And the device is locked
+            kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
+                AuthenticationMethodModel.Pin
+            )
+
+            // When the user expands a sensitive Notification
+            val entry =
+                createRow().entry.apply {
+                    setSensitive(/* sensitive= */ true, /* deviceSensitive= */ true)
+                }
+            underTest.onExpandClicked(entry, mock(), /* nowExpanded= */ true)
+
+            // Then we open the locked shade
+            assertThat(kosmos.sysuiStatusBarStateController.state)
+                .isEqualTo(StatusBarState.SHADE_LOCKED)
+        }
+
+    @Test
+    @EnableSceneContainer
+    fun testExpandSensitiveNotification_onLockedShade_showsBouncer() =
+        kosmos.runTest {
+            // Given we are on the locked shade
+            kosmos.sysuiStatusBarStateController.state = StatusBarState.SHADE_LOCKED
+            // And the device is locked
+            kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
+                AuthenticationMethodModel.Pin
+            )
+
+            // When the user expands a sensitive Notification
+            val entry =
+                createRow().entry.apply {
+                    setSensitive(/* sensitive= */ true, /* deviceSensitive= */ true)
+                }
+            underTest.onExpandClicked(entry, mock(), /* nowExpanded= */ true)
+
+            // Then we show the bouncer
+            verify(kosmos.activityStarter).dismissKeyguardThenExecute(any(), eq(null), eq(false))
+            // AND we are still on the locked shade
+            assertThat(kosmos.sysuiStatusBarStateController.state)
+                .isEqualTo(StatusBarState.SHADE_LOCKED)
+        }
+
+    private fun createPresenter(): StatusBarNotificationPresenter {
+        val shadeViewController: ShadeViewController = mock()
+
+        val notificationShadeWindowView: NotificationShadeWindowView = mock()
+        whenever(notificationShadeWindowView.resources).thenReturn(mContext.resources)
+        whenever(kosmos.notificationStackScrollLayoutController.view).thenReturn(mock())
+
+        val initController: InitController = InitController()
+
+        return StatusBarNotificationPresenter(
+                mContext,
+                shadeViewController,
+                kosmos.panelExpansionInteractor,
+                /* quickSettingsController = */ mock(),
+                kosmos.headsUpManager,
+                notificationShadeWindowView,
+                kosmos.activityStarter,
+                kosmos.notificationStackScrollLayoutController,
+                kosmos.dozeScrimController,
+                kosmos.notificationShadeWindowController,
+                kosmos.dynamicPrivacyController,
+                kosmos.keyguardStateController,
+                kosmos.notificationAlertsInteractor,
+                kosmos.lockscreenShadeTransitionController,
+                kosmos.powerInteractor,
+                commandQueue,
+                kosmos.notificationLockscreenUserManager,
+                kosmos.sysuiStatusBarStateController,
+                /* notifShadeEventSource = */ mock(),
+                /* notificationMediaManager = */ mock(),
+                /* notificationGutsManager = */ mock(),
+                initController,
+                kosmos.visualInterruptionDecisionProvider,
+                kosmos.notificationRemoteInputManager,
+                /* remoteInputManagerCallback = */ mock(),
+                /* notificationListContainer = */ mock(),
+                kosmos.deviceUnlockedInteractor,
+            )
+            .also { initController.executePostInitTasks() }
+    }
+
+    private fun verifyAndCaptureSuppressors() {
+        interruptSuppressor = null
+
+        val conditionCaptor = argumentCaptor<VisualInterruptionCondition>()
+        verify(visualInterruptionDecisionProvider, times(3)).addCondition(conditionCaptor.capture())
+        val conditions: List<VisualInterruptionCondition> = conditionCaptor.allValues
+        alertsDisabledCondition = conditions[0]
+        vrModeCondition = conditions[1]
+        panelsDisabledCondition = conditions[2]
+
+        val needsRedactionFilterCaptor = argumentCaptor<VisualInterruptionFilter>()
+        verify(visualInterruptionDecisionProvider).addFilter(needsRedactionFilterCaptor.capture())
+        needsRedactionFilter = needsRedactionFilterCaptor.lastValue
+    }
+
+    private fun verifyAndCaptureLegacySuppressor() {
+        alertsDisabledCondition = null
+        vrModeCondition = null
+        needsRedactionFilter = null
+        panelsDisabledCondition = null
+
+        val suppressorCaptor = argumentCaptor<NotificationInterruptSuppressor>()
+        verify(visualInterruptionDecisionProvider).addLegacySuppressor(suppressorCaptor.capture())
+        interruptSuppressor = suppressorCaptor.lastValue
+    }
+
+    private fun createRow(): ExpandableNotificationRow {
+        val row: ExpandableNotificationRow = mock()
+        val entry: NotificationEntry = createNotificationEntry()
+        whenever(row.entry).thenReturn(entry)
+        entry.row = row
+        return row
+    }
+
+    private fun createNotificationEntry(): NotificationEntry =
+        NotificationEntryBuilder()
+            .setPkg("a")
+            .setOpPkg("a")
+            .setTag("a")
+            .setNotification(Builder(mContext, "a").build())
+            .build()
+
+    private fun createFsiNotificationEntry(): NotificationEntry {
+        val notification: Notification =
+            Builder(mContext, "a").setFullScreenIntent(mock(), true).build()
+
+        return NotificationEntryBuilder()
+            .setPkg("a")
+            .setOpPkg("a")
+            .setTag("a")
+            .setNotification(notification)
+            .build()
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt
index ca1413e..b19645f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt
@@ -30,11 +30,13 @@
 import com.android.systemui.kosmos.runTest
 import com.android.systemui.kosmos.useUnconfinedTestDispatcher
 import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.data.repository.fakeStatusBarModeRepository
 import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
 import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore
 import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
 import com.android.systemui.statusbar.notification.shared.CallType
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
+import com.android.systemui.statusbar.window.fakeStatusBarWindowControllerStore
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runTest
@@ -72,7 +74,7 @@
                                 whenTime = 1000L,
                                 callType = CallType.Ongoing,
                                 statusBarChipIcon = testIconView,
-                                contentIntent = testIntent
+                                contentIntent = testIntent,
                             )
                         )
                     }
@@ -95,7 +97,9 @@
                     .apply {
                         addIndividualNotif(
                             activeNotificationModel(
-                                key = "notif1", whenTime = 1000L, callType = CallType.Ongoing
+                                key = "notif1",
+                                whenTime = 1000L,
+                                callType = CallType.Ongoing,
                             )
                         )
                     }
@@ -114,7 +118,9 @@
                     .apply {
                         addIndividualNotif(
                             activeNotificationModel(
-                                key = "notif1", whenTime = 1000L, callType = CallType.Ongoing
+                                key = "notif1",
+                                whenTime = 1000L,
+                                callType = CallType.Ongoing,
                             )
                         )
                     }
@@ -138,7 +144,7 @@
                                 key = "notif1",
                                 whenTime = 1000L,
                                 callType = CallType.Ongoing,
-                                uid = UID
+                                uid = UID,
                             )
                         )
                     }
@@ -161,7 +167,7 @@
                                 key = "notif1",
                                 whenTime = 1000L,
                                 callType = CallType.Ongoing,
-                                uid = UID
+                                uid = UID,
                             )
                         )
                     }
@@ -185,13 +191,12 @@
                                 key = "notif1",
                                 whenTime = 1000L,
                                 callType = CallType.Ongoing,
-                                uid = UID
+                                uid = UID,
                             )
                         )
                     }
                     .build()
-            assertThat(latest)
-                .isInstanceOf(OngoingCallModel.InCall::class.java)
+            assertThat(latest).isInstanceOf(OngoingCallModel.InCall::class.java)
 
             // App becomes visible
             kosmos.activityManagerRepository.fake.setIsAppVisible(UID, true)
@@ -202,6 +207,120 @@
             assertThat(latest).isInstanceOf(OngoingCallModel.InCall::class.java)
         }
 
+    @Test
+    fun ongoingCallNotification_setsRequiresStatusBarVisibleTrue() =
+        kosmos.runTest {
+            val ongoingCallState by collectLastValue(underTest.ongoingCallState)
+
+            val requiresStatusBarVisibleInRepository by
+                collectLastValue(
+                    kosmos.fakeStatusBarModeRepository.defaultDisplay
+                        .ongoingProcessRequiresStatusBarVisible
+                )
+            val requiresStatusBarVisibleInWindowController by
+                collectLastValue(
+                    kosmos.fakeStatusBarWindowControllerStore.defaultDisplay
+                        .ongoingProcessRequiresStatusBarVisible
+                )
+            repository.activeNotifications.value =
+                ActiveNotificationsStore.Builder()
+                    .apply {
+                        addIndividualNotif(
+                            activeNotificationModel(
+                                key = "notif1",
+                                whenTime = 1000L,
+                                callType = CallType.Ongoing,
+                                uid = UID,
+                            )
+                        )
+                    }
+                    .build()
+
+            assertThat(ongoingCallState).isInstanceOf(OngoingCallModel.InCall::class.java)
+            assertThat(requiresStatusBarVisibleInRepository).isTrue()
+            assertThat(requiresStatusBarVisibleInWindowController).isTrue()
+        }
+
+    @Test
+    fun notificationRemoved_setsRequiresStatusBarVisibleFalse() =
+        kosmos.runTest {
+            val ongoingCallState by collectLastValue(underTest.ongoingCallState)
+
+            val requiresStatusBarVisibleInRepository by
+                collectLastValue(
+                    kosmos.fakeStatusBarModeRepository.defaultDisplay
+                        .ongoingProcessRequiresStatusBarVisible
+                )
+            val requiresStatusBarVisibleInWindowController by
+                collectLastValue(
+                    kosmos.fakeStatusBarWindowControllerStore.defaultDisplay
+                        .ongoingProcessRequiresStatusBarVisible
+                )
+
+            repository.activeNotifications.value =
+                ActiveNotificationsStore.Builder()
+                    .apply {
+                        addIndividualNotif(
+                            activeNotificationModel(
+                                key = "notif1",
+                                whenTime = 1000L,
+                                callType = CallType.Ongoing,
+                                uid = UID,
+                            )
+                        )
+                    }
+                    .build()
+
+            repository.activeNotifications.value = ActiveNotificationsStore()
+
+            assertThat(ongoingCallState).isInstanceOf(OngoingCallModel.NoCall::class.java)
+            assertThat(requiresStatusBarVisibleInRepository).isFalse()
+            assertThat(requiresStatusBarVisibleInWindowController).isFalse()
+        }
+
+    @Test
+    fun ongoingCallNotification_appBecomesVisible_setsRequiresStatusBarVisibleFalse() =
+        kosmos.runTest {
+            val ongoingCallState by collectLastValue(underTest.ongoingCallState)
+
+            val requiresStatusBarVisibleInRepository by
+                collectLastValue(
+                    kosmos.fakeStatusBarModeRepository.defaultDisplay
+                        .ongoingProcessRequiresStatusBarVisible
+                )
+            val requiresStatusBarVisibleInWindowController by
+                collectLastValue(
+                    kosmos.fakeStatusBarWindowControllerStore.defaultDisplay
+                        .ongoingProcessRequiresStatusBarVisible
+                )
+
+            kosmos.activityManagerRepository.fake.startingIsAppVisibleValue = false
+            repository.activeNotifications.value =
+                ActiveNotificationsStore.Builder()
+                    .apply {
+                        addIndividualNotif(
+                            activeNotificationModel(
+                                key = "notif1",
+                                whenTime = 1000L,
+                                callType = CallType.Ongoing,
+                                uid = UID,
+                            )
+                        )
+                    }
+                    .build()
+
+            assertThat(ongoingCallState).isInstanceOf(OngoingCallModel.InCall::class.java)
+            assertThat(requiresStatusBarVisibleInRepository).isTrue()
+            assertThat(requiresStatusBarVisibleInWindowController).isTrue()
+
+            kosmos.activityManagerRepository.fake.setIsAppVisible(UID, true)
+
+            assertThat(ongoingCallState)
+                .isInstanceOf(OngoingCallModel.InCallWithVisibleApp::class.java)
+            assertThat(requiresStatusBarVisibleInRepository).isFalse()
+            assertThat(requiresStatusBarVisibleInWindowController).isFalse()
+        }
+
     companion object {
         private const val UID = 885
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
index 038722c..bf1fbad 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
@@ -20,8 +20,6 @@
 import android.platform.test.annotations.EnableFlags
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.settingslib.AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH
-import com.android.settingslib.AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH_NONE
 import com.android.settingslib.mobile.MobileMappings
 import com.android.settingslib.mobile.TelephonyIcons.G
 import com.android.settingslib.mobile.TelephonyIcons.THREE_G
@@ -40,12 +38,15 @@
 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.model.DataConnectionState
+import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository.Companion.DEFAULT_NETWORK_NAME
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorImpl
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractorImpl
 import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
+import com.android.systemui.statusbar.pipeline.mobile.ui.model.MobileContentDescription
 import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
 import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
@@ -255,59 +256,146 @@
     @Test
     fun contentDescription_notInService_usesNoPhone() =
         testScope.runTest {
-            var latest: ContentDescription? = null
-            val job = underTest.contentDescription.onEach { latest = it }.launchIn(this)
+            val latest by collectLastValue(underTest.contentDescription)
 
             repository.isInService.value = false
 
-            assertThat((latest as ContentDescription.Resource).res)
-                .isEqualTo(PHONE_SIGNAL_STRENGTH_NONE)
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+        }
 
-            job.cancel()
+    @Test
+    fun contentDescription_includesNetworkName() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.contentDescription)
+
+            repository.isInService.value = true
+            repository.networkName.value = NetworkNameModel.SubscriptionDerived("Test Network Name")
+            repository.numberOfLevels.value = 5
+            repository.setAllLevels(3)
+
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular("Test Network Name", THREE_BARS))
         }
 
     @Test
     fun contentDescription_inService_usesLevel() =
         testScope.runTest {
-            var latest: ContentDescription? = null
-            val job = underTest.contentDescription.onEach { latest = it }.launchIn(this)
+            val latest by collectLastValue(underTest.contentDescription)
 
             repository.setAllLevels(2)
-            assertThat((latest as ContentDescription.Resource).res)
-                .isEqualTo(PHONE_SIGNAL_STRENGTH[2])
+
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
 
             repository.setAllLevels(0)
-            assertThat((latest as ContentDescription.Resource).res)
-                .isEqualTo(PHONE_SIGNAL_STRENGTH[0])
 
-            job.cancel()
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
         }
 
     @Test
-    fun contentDescription_nonInflated_invalidLevelIsNull() =
+    fun contentDescription_nonInflated_invalidLevelUsesNoSignalText() =
         testScope.runTest {
             val latest by collectLastValue(underTest.contentDescription)
 
             repository.inflateSignalStrength.value = false
             repository.setAllLevels(-1)
-            assertThat(latest).isNull()
+
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
 
             repository.setAllLevels(100)
-            assertThat(latest).isNull()
+
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
         }
 
     @Test
-    fun contentDescription_inflated_invalidLevelIsNull() =
+    fun contentDescription_nonInflated_levelStrings() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.contentDescription)
+
+            repository.inflateSignalStrength.value = false
+            repository.setAllLevels(0)
+
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+
+            repository.setAllLevels(1)
+
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, ONE_BAR))
+
+            repository.setAllLevels(2)
+
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
+
+            repository.setAllLevels(3)
+
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, THREE_BARS))
+
+            repository.setAllLevels(4)
+
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FULL_BARS))
+        }
+
+    @Test
+    fun contentDescription_inflated_invalidLevelUsesNoSignalText() =
         testScope.runTest {
             val latest by collectLastValue(underTest.contentDescription)
 
             repository.inflateSignalStrength.value = true
             repository.numberOfLevels.value = 6
+
             repository.setAllLevels(-2)
-            assertThat(latest).isNull()
+
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
 
             repository.setAllLevels(100)
-            assertThat(latest).isNull()
+
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+        }
+
+    @Test
+    fun contentDescription_inflated_levelStrings() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.contentDescription)
+
+            repository.inflateSignalStrength.value = true
+            repository.numberOfLevels.value = 6
+
+            // Note that the _repo_ level is 1 lower than the reported level through the interactor
+
+            repository.setAllLevels(0)
+
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, ONE_BAR))
+
+            repository.setAllLevels(1)
+
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
+
+            repository.setAllLevels(2)
+
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, THREE_BARS))
+
+            repository.setAllLevels(3)
+
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FOUR_BARS))
+
+            repository.setAllLevels(4)
+
+            assertThat(latest as MobileContentDescription.Cellular)
+                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FULL_BARS))
         }
 
     @Test
@@ -323,7 +411,10 @@
                 repository.setAllLevels(i)
                 when (i) {
                     -1,
-                    5 -> assertWithMessage("Level $i is expected to be null").that(latest).isNull()
+                    5 ->
+                        assertWithMessage("Level $i is expected to be 'no signal'")
+                            .that((latest as MobileContentDescription.Cellular).levelDescriptionRes)
+                            .isEqualTo(NO_SIGNAL)
                     else ->
                         assertWithMessage("Level $i is expected not to be null")
                             .that(latest)
@@ -344,7 +435,10 @@
                 repository.setAllLevels(i)
                 when (i) {
                     -2,
-                    5 -> assertWithMessage("Level $i is expected to be null").that(latest).isNull()
+                    5 ->
+                        assertWithMessage("Level $i is expected to be 'no signal'")
+                            .that((latest as MobileContentDescription.Cellular).levelDescriptionRes)
+                            .isEqualTo(NO_SIGNAL)
                     else ->
                         assertWithMessage("Level $i is not expected to be null")
                             .that(latest)
@@ -967,5 +1061,13 @@
 
     companion object {
         private const val SUB_1_ID = 1
+
+        // For convenience, just define these as constants
+        private val NO_SIGNAL = R.string.accessibility_no_signal
+        private val ONE_BAR = R.string.accessibility_one_bar
+        private val TWO_BARS = R.string.accessibility_two_bars
+        private val THREE_BARS = R.string.accessibility_three_bars
+        private val FOUR_BARS = R.string.accessibility_four_bars
+        private val FULL_BARS = R.string.accessibility_signal_full
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
index c0a206a..9ad2315 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
@@ -49,11 +49,7 @@
     private val dispatcher = StandardTestDispatcher()
     private val testScope = TestScope(dispatcher)
 
-    private val iconsInteractor =
-        FakeMobileIconsInteractor(
-            FakeMobileMappingsProxy(),
-            mock(),
-        )
+    private val iconsInteractor = FakeMobileIconsInteractor(FakeMobileMappingsProxy(), mock())
 
     private val repo = FakeDeviceBasedSatelliteRepository()
     private val connectivityRepository = FakeConnectivityRepository()
@@ -515,7 +511,7 @@
 
             // GIVEN, 2 connection
             val i1 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
-            val i2 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
+            val i2 = iconsInteractor.getMobileConnectionInteractorForSubId(2)
 
             // WHEN all connections are NOT OOS.
             i1.isInService.value = true
@@ -547,7 +543,7 @@
             // GIVEN a condition that should return true (all conections OOS)
 
             val i1 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
-            val i2 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
+            val i2 = iconsInteractor.getMobileConnectionInteractorForSubId(2)
 
             i1.isInService.value = true
             i2.isInService.value = true
@@ -579,4 +575,40 @@
             // THEN the interactor returns true due to the wifi network being active
             assertThat(latest).isTrue()
         }
+
+    @Test
+    @EnableFlags(FLAG_OEM_ENABLED_SATELLITE_FLAG)
+    fun isAnyConnectionNtn_trueWhenAnyNtn() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.isAnyConnectionNtn)
+
+            // GIVEN, 2 connection
+            val i1 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
+            val i2 = iconsInteractor.getMobileConnectionInteractorForSubId(2)
+
+            // WHEN at least one connection is using ntn
+            i1.isNonTerrestrial.value = true
+            i2.isNonTerrestrial.value = false
+
+            // THEN the value is propagated to this interactor
+            assertThat(latest).isTrue()
+        }
+
+    @Test
+    @EnableFlags(FLAG_OEM_ENABLED_SATELLITE_FLAG)
+    fun isAnyConnectionNtn_falseWhenNoNtn() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.isAnyConnectionNtn)
+
+            // GIVEN, 2 connection
+            val i1 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
+            val i2 = iconsInteractor.getMobileConnectionInteractorForSubId(2)
+
+            // WHEN at no connection is using ntn
+            i1.isNonTerrestrial.value = false
+            i2.isNonTerrestrial.value = false
+
+            // THEN the value is propagated to this interactor
+            assertThat(latest).isFalse()
+        }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
index 509aa7a..fe5b56a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
@@ -327,10 +327,11 @@
             // GIVEN satellite is allowed
             repo.isSatelliteAllowedForCurrentLocation.value = true
 
-            // GIVEN all icons are OOS
+            // GIVEN all icons are OOS and not ntn
             val i1 = mobileIconsInteractor.getMobileConnectionInteractorForSubId(1)
             i1.isInService.value = false
             i1.isEmergencyOnly.value = false
+            i1.isNonTerrestrial.value = false
 
             // GIVEN apm is disabled
             airplaneModeRepository.setIsAirplaneMode(false)
@@ -344,6 +345,29 @@
         }
 
     @Test
+    fun icon_nullWhenConnected_mobileNtnConnectionExists() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.icon)
+
+            // GIVEN satellite is allowed
+            repo.isSatelliteAllowedForCurrentLocation.value = true
+
+            // GIVEN ntn connection exists
+            val i1 = mobileIconsInteractor.getMobileConnectionInteractorForSubId(1)
+            i1.isNonTerrestrial.value = true
+
+            // GIVEN apm is disabled
+            airplaneModeRepository.setIsAirplaneMode(false)
+
+            // GIVEN satellite reports that it is Connected
+            repo.connectionState.value = SatelliteConnectionState.On
+
+            // THEN icon is null because despite being connected, the mobile stack is reporting a
+            // nonTerrestrial network, and therefore will have its own icon
+            assertThat(latest).isNull()
+        }
+
+    @Test
     fun icon_satelliteIsProvisioned() =
         testScope.runTest {
             val latest by collectLastValue(underTest.icon)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
index 7b04fc8..5c1141b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
@@ -67,8 +67,9 @@
 import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle
 import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
 import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore
-import com.android.systemui.statusbar.notification.data.repository.FakeHeadsUpRowRepository
+import com.android.systemui.statusbar.notification.data.repository.UnconfinedFakeHeadsUpRowRepository
 import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus
 import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
 import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
 import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository
@@ -76,6 +77,7 @@
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import org.junit.Before
@@ -518,7 +520,8 @@
         }
 
     @Test
-    fun isClockVisible_allowedByFlags_hunActive_notVisible() =
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    fun isClockVisible_allowedByFlags_hunPinnedByUser_visible() =
         kosmos.runTest {
             val latest by collectLastValue(underTest.isClockVisible)
             transitionKeyguardToGone()
@@ -527,7 +530,29 @@
                 DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE)
             // there is an active HUN
             headsUpNotificationRepository.setNotifications(
-                fakeHeadsUpRowRepository(isPinned = true)
+                UnconfinedFakeHeadsUpRowRepository(
+                    key = "key",
+                    pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
+                )
+            )
+
+            assertThat(latest!!.visibility).isEqualTo(View.VISIBLE)
+        }
+
+    @Test
+    fun isClockVisible_allowedByFlags_hunPinnedBySystem_notVisible() =
+        kosmos.runTest {
+            val latest by collectLastValue(underTest.isClockVisible)
+            transitionKeyguardToGone()
+
+            fakeDisableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE)
+            // there is an active HUN
+            headsUpNotificationRepository.setNotifications(
+                UnconfinedFakeHeadsUpRowRepository(
+                    key = "key",
+                    pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
+                )
             )
 
             assertThat(latest!!.visibility).isEqualTo(View.INVISIBLE)
@@ -541,10 +566,14 @@
 
             fakeDisableFlagsRepository.disableFlags.value =
                 DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE)
-            // there is an active HUN
+            // there is an active HUN pinned by the system
             headsUpNotificationRepository.setNotifications(
-                fakeHeadsUpRowRepository(isPinned = true)
+                UnconfinedFakeHeadsUpRowRepository(
+                    key = "key",
+                    pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
+                )
             )
+            assertThat(latest!!.visibility).isEqualTo(View.INVISIBLE)
 
             // hun goes away
             headsUpNotificationRepository.setNotifications(listOf())
@@ -562,7 +591,10 @@
                 DisableFlagsModel(DISABLE_CLOCK, DISABLE2_NONE)
             // there is an active HUN
             headsUpNotificationRepository.setNotifications(
-                fakeHeadsUpRowRepository(isPinned = true)
+                UnconfinedFakeHeadsUpRowRepository(
+                    key = "key",
+                    pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
+                )
             )
 
             assertThat(latest!!.visibility).isEqualTo(View.INVISIBLE)
@@ -898,10 +930,6 @@
             assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
         }
 
-    // Cribbed from [HeadsUpNotificationInteractorTest.kt]
-    private fun fakeHeadsUpRowRepository(key: String = "test key", isPinned: Boolean = false) =
-        FakeHeadsUpRowRepository(key = key, isPinned = isPinned)
-
     private fun activeNotificationsStore(notifications: List<ActiveNotificationModel>) =
         ActiveNotificationsStore.Builder()
             .apply { notifications.forEach(::addIndividualNotif) }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt
index 1b7b47f..2eac39e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt
@@ -66,7 +66,7 @@
             doAnswer {
                     // See Utils.isHeadlessRemoteDisplayProvider
                     if ((it.arguments[0] as Intent).`package` == HEADLESS_REMOTE_PACKAGE) {
-                        emptyList()
+                        emptyList<ResolveInfo>()
                     } else {
                         listOf(mock<ResolveInfo>())
                     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizerTest.kt
index d9d8169..2f3f75f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizerTest.kt
@@ -22,7 +22,6 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureDirection.LEFT
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureDirection.RIGHT
-import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.Finished
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.NotStarted
 import com.android.systemui.touchpad.tutorial.ui.gesture.MultiFingerGesture.Companion.SWIPE_DISTANCE
@@ -45,24 +44,6 @@
     }
 
     @Test
-    fun triggersGestureFinishedForThreeFingerGestureRight() {
-        assertStateAfterEvents(events = ThreeFingerGesture.swipeRight(), expectedState = Finished)
-    }
-
-    @Test
-    fun triggersGestureFinishedForThreeFingerGestureLeft() {
-        assertStateAfterEvents(events = ThreeFingerGesture.swipeLeft(), expectedState = Finished)
-    }
-
-    @Test
-    fun triggersGestureProgressForThreeFingerGestureStarted() {
-        assertStateAfterEvents(
-            events = ThreeFingerGesture.startEvents(x = 0f, y = 0f),
-            expectedState = InProgress(),
-        )
-    }
-
-    @Test
     fun triggersProgressRelativeToDistanceWhenSwipingLeft() {
         assertProgressWhileMovingFingers(
             deltaX = -SWIPE_DISTANCE / 2,
@@ -86,13 +67,6 @@
         )
     }
 
-    private fun assertProgressWhileMovingFingers(deltaX: Float, expected: InProgress) {
-        assertStateAfterEvents(
-            events = ThreeFingerGesture.eventsForGestureInProgress { move(deltaX = deltaX) },
-            expectedState = expected,
-        )
-    }
-
     @Test
     fun triggeredProgressIsNoBiggerThanOne() {
         assertProgressWhileMovingFingers(
@@ -105,30 +79,13 @@
         )
     }
 
-    @Test
-    fun doesntTriggerGestureFinished_onGestureDistanceTooShort() {
+    private fun assertProgressWhileMovingFingers(deltaX: Float, expected: InProgress) {
         assertStateAfterEvents(
-            events = ThreeFingerGesture.swipeLeft(distancePx = SWIPE_DISTANCE / 2),
-            expectedState = NotStarted,
+            events = ThreeFingerGesture.eventsForGestureInProgress { move(deltaX = deltaX) },
+            expectedState = expected,
         )
     }
 
-    @Test
-    fun doesntTriggerGestureFinished_onThreeFingersSwipeInOtherDirections() {
-        assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = NotStarted)
-        assertStateAfterEvents(events = ThreeFingerGesture.swipeDown(), expectedState = NotStarted)
-    }
-
-    @Test
-    fun doesntTriggerGestureFinished_onTwoFingersSwipe() {
-        assertStateAfterEvents(events = TwoFingerGesture.swipeRight(), expectedState = NotStarted)
-    }
-
-    @Test
-    fun doesntTriggerGestureFinished_onFourFingersSwipe() {
-        assertStateAfterEvents(events = FourFingerGesture.swipeRight(), expectedState = NotStarted)
-    }
-
     private fun assertStateAfterEvents(events: List<MotionEvent>, expectedState: GestureState) {
         events.forEach { gestureRecognizer.accept(it) }
         assertThat(gestureState).isEqualTo(expectedState)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizerTest.kt
index 7aa389a..8d0d172 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizerTest.kt
@@ -21,7 +21,6 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.testKosmos
-import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.Finished
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.NotStarted
 import com.android.systemui.touchpad.tutorial.ui.gesture.MultiFingerGesture.Companion.SWIPE_DISTANCE
@@ -57,37 +56,17 @@
     }
 
     @Test
-    fun triggersGestureFinishedForThreeFingerGestureUp() {
-        assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = Finished)
-    }
-
-    @Test
     fun doesntTriggerGestureFinished_onGestureSpeedTooSlow() {
         velocityTracker.setVelocity(Velocity(SLOW))
         assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = NotStarted)
     }
 
     @Test
-    fun triggersGestureProgressForThreeFingerGestureStarted() {
-        assertStateAfterEvents(
-            events = ThreeFingerGesture.startEvents(x = 0f, y = 0f),
-            expectedState = InProgress(),
-        )
-    }
-
-    @Test
     fun triggersProgressRelativeToDistance() {
         assertProgressWhileMovingFingers(deltaY = -SWIPE_DISTANCE / 2, expectedProgress = 0.5f)
         assertProgressWhileMovingFingers(deltaY = -SWIPE_DISTANCE, expectedProgress = 1f)
     }
 
-    private fun assertProgressWhileMovingFingers(deltaY: Float, expectedProgress: Float) {
-        assertStateAfterEvents(
-            events = ThreeFingerGesture.eventsForGestureInProgress { move(deltaY = deltaY) },
-            expectedState = InProgress(progress = expectedProgress),
-        )
-    }
-
     @Test
     fun triggeredProgressIsBetweenZeroAndOne() {
         // going in the wrong direction
@@ -96,31 +75,13 @@
         assertProgressWhileMovingFingers(deltaY = -SWIPE_DISTANCE * 2, expectedProgress = 1f)
     }
 
-    @Test
-    fun doesntTriggerGestureFinished_onGestureDistanceTooShort() {
+    private fun assertProgressWhileMovingFingers(deltaY: Float, expectedProgress: Float) {
         assertStateAfterEvents(
-            events = ThreeFingerGesture.swipeUp(distancePx = SWIPE_DISTANCE / 2),
-            expectedState = NotStarted,
+            events = ThreeFingerGesture.eventsForGestureInProgress { move(deltaY = deltaY) },
+            expectedState = InProgress(progress = expectedProgress),
         )
     }
 
-    @Test
-    fun doesntTriggerGestureFinished_onThreeFingersSwipeInOtherDirections() {
-        assertStateAfterEvents(events = ThreeFingerGesture.swipeDown(), expectedState = NotStarted)
-        assertStateAfterEvents(events = ThreeFingerGesture.swipeLeft(), expectedState = NotStarted)
-        assertStateAfterEvents(events = ThreeFingerGesture.swipeRight(), expectedState = NotStarted)
-    }
-
-    @Test
-    fun doesntTriggerGestureFinished_onTwoFingersSwipe() {
-        assertStateAfterEvents(events = TwoFingerGesture.swipeUp(), expectedState = NotStarted)
-    }
-
-    @Test
-    fun doesntTriggerGestureFinished_onFourFingersSwipe() {
-        assertStateAfterEvents(events = FourFingerGesture.swipeUp(), expectedState = NotStarted)
-    }
-
     private fun assertStateAfterEvents(events: List<MotionEvent>, expectedState: GestureState) {
         events.forEach { gestureRecognizer.accept(it) }
         assertThat(gestureState).isEqualTo(expectedState)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizerTest.kt
index cb74e65..7a77b63 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizerTest.kt
@@ -21,7 +21,6 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.testKosmos
-import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.Finished
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.NotStarted
 import com.android.systemui.touchpad.tutorial.ui.gesture.MultiFingerGesture.Companion.SWIPE_DISTANCE
@@ -58,25 +57,12 @@
     }
 
     @Test
-    fun triggersGestureFinishedForThreeFingerGestureUp() {
-        assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = Finished)
-    }
-
-    @Test
     fun doesntTriggerGestureFinished_onGestureSpeedTooHigh() {
         velocityTracker.setVelocity(Velocity(FAST))
         assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = NotStarted)
     }
 
     @Test
-    fun triggersGestureProgressForThreeFingerGestureStarted() {
-        assertStateAfterEvents(
-            events = ThreeFingerGesture.startEvents(x = 0f, y = 0f),
-            expectedState = InProgress(progress = 0f),
-        )
-    }
-
-    @Test
     fun triggersProgressRelativeToDistance() {
         assertProgressWhileMovingFingers(deltaY = -SWIPE_DISTANCE / 2, expectedProgress = 0.5f)
         assertProgressWhileMovingFingers(deltaY = -SWIPE_DISTANCE, expectedProgress = 1f)
@@ -97,31 +83,6 @@
         assertProgressWhileMovingFingers(deltaY = -SWIPE_DISTANCE * 2, expectedProgress = 1f)
     }
 
-    @Test
-    fun doesntTriggerGestureFinished_onGestureDistanceTooShort() {
-        assertStateAfterEvents(
-            events = ThreeFingerGesture.swipeUp(distancePx = SWIPE_DISTANCE / 2),
-            expectedState = NotStarted,
-        )
-    }
-
-    @Test
-    fun doesntTriggerGestureFinished_onThreeFingersSwipeInOtherDirections() {
-        assertStateAfterEvents(events = ThreeFingerGesture.swipeDown(), expectedState = NotStarted)
-        assertStateAfterEvents(events = ThreeFingerGesture.swipeLeft(), expectedState = NotStarted)
-        assertStateAfterEvents(events = ThreeFingerGesture.swipeRight(), expectedState = NotStarted)
-    }
-
-    @Test
-    fun doesntTriggerGestureFinished_onTwoFingersSwipe() {
-        assertStateAfterEvents(events = TwoFingerGesture.swipeUp(), expectedState = NotStarted)
-    }
-
-    @Test
-    fun doesntTriggerGestureFinished_onFourFingersSwipe() {
-        assertStateAfterEvents(events = FourFingerGesture.swipeUp(), expectedState = NotStarted)
-    }
-
     private fun assertStateAfterEvents(events: List<MotionEvent>, expectedState: GestureState) {
         events.forEach { gestureRecognizer.accept(it) }
         assertThat(gestureState).isEqualTo(expectedState)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/ThreeFingerGestureRecognizerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/ThreeFingerGestureRecognizerTest.kt
new file mode 100644
index 0000000..de41089
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/ThreeFingerGestureRecognizerTest.kt
@@ -0,0 +1,153 @@
+/*
+ * 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.touchpad.tutorial.ui.gesture
+
+import android.view.MotionEvent
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.Finished
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.NotStarted
+import com.android.systemui.touchpad.tutorial.ui.gesture.MultiFingerGesture.Companion.SWIPE_DISTANCE
+import com.android.systemui.touchpad.tutorial.ui.gesture.RecentAppsGestureRecognizerTest.Companion.FAST
+import com.android.systemui.touchpad.tutorial.ui.gesture.RecentAppsGestureRecognizerTest.Companion.SLOW
+import com.android.systemui.touchpad.tutorial.ui.gesture.RecentAppsGestureRecognizerTest.Companion.THRESHOLD_VELOCITY_PX_PER_MS
+import com.android.systemui.touchpad.ui.gesture.FakeVelocityTracker
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+
+@SmallTest
+@RunWith(ParameterizedAndroidJunit4::class)
+class ThreeFingerGestureRecognizerTest(
+    private val recognizer: GestureRecognizer,
+    private val validGestures: Set<List<MotionEvent>>,
+    private val tooShortGesture: List<MotionEvent>,
+    @Suppress("UNUSED_PARAMETER") testSuffix: String, // here just for nicer test names
+) : SysuiTestCase() {
+
+    private var gestureState: GestureState = GestureState.NotStarted
+
+    @Before
+    fun before() {
+        recognizer.addGestureStateCallback { gestureState = it }
+    }
+
+    @Test
+    fun triggersGestureFinishedForValidGestures() {
+        validGestures.forEach { assertStateAfterEvents(events = it, expectedState = Finished) }
+    }
+
+    @Test
+    fun triggersGestureProgressForThreeFingerGestureStarted() {
+        assertStateAfterEvents(
+            events = ThreeFingerGesture.startEvents(x = 0f, y = 0f),
+            expectedState = InProgress(progress = 0f),
+        )
+    }
+
+    @Test
+    fun doesntTriggerGestureFinished_onGestureDistanceTooShort() {
+        assertStateAfterEvents(events = tooShortGesture, expectedState = NotStarted)
+    }
+
+    @Test
+    fun doesntTriggerGestureFinished_onThreeFingersSwipeInOtherDirections() {
+        val allThreeFingerGestures =
+            listOf(
+                ThreeFingerGesture.swipeUp(),
+                ThreeFingerGesture.swipeDown(),
+                ThreeFingerGesture.swipeLeft(),
+                ThreeFingerGesture.swipeRight(),
+            )
+        val invalidGestures = allThreeFingerGestures.filter { it.differentFromAnyOf(validGestures) }
+        invalidGestures.forEach { assertStateAfterEvents(events = it, expectedState = NotStarted) }
+    }
+
+    @Test
+    fun doesntTriggerGestureFinished_onTwoFingersSwipe() {
+        assertStateAfterEvents(events = TwoFingerGesture.swipeRight(), expectedState = NotStarted)
+    }
+
+    @Test
+    fun doesntTriggerGestureFinished_onFourFingersSwipe() {
+        assertStateAfterEvents(events = FourFingerGesture.swipeRight(), expectedState = NotStarted)
+    }
+
+    private fun assertStateAfterEvents(events: List<MotionEvent>, expectedState: GestureState) {
+        events.forEach { recognizer.accept(it) }
+        assertThat(gestureState).isEqualTo(expectedState)
+    }
+
+    companion object {
+        @JvmStatic
+        @Parameters(name = "{3}")
+        fun gesturesToTest(): List<Array<Any>> =
+            with(ThreeFingerGesture) {
+                listOf(
+                        GestureTestData(
+                            recognizer = BackGestureRecognizer(SWIPE_DISTANCE.toInt()),
+                            validGestures = setOf(swipeRight(), swipeLeft()),
+                            tooShortGesture = swipeRight(SWIPE_DISTANCE / 2),
+                            testSuffix = "back gesture",
+                        ),
+                        GestureTestData(
+                            recognizer =
+                                HomeGestureRecognizer(
+                                    SWIPE_DISTANCE.toInt(),
+                                    THRESHOLD_VELOCITY_PX_PER_MS,
+                                    FakeVelocityTracker(velocity = FAST),
+                                ),
+                            validGestures = setOf(swipeUp()),
+                            tooShortGesture = swipeUp(SWIPE_DISTANCE / 2),
+                            testSuffix = "home gesture",
+                        ),
+                        GestureTestData(
+                            recognizer =
+                                RecentAppsGestureRecognizer(
+                                    SWIPE_DISTANCE.toInt(),
+                                    THRESHOLD_VELOCITY_PX_PER_MS,
+                                    FakeVelocityTracker(velocity = SLOW),
+                                ),
+                            validGestures = setOf(swipeUp()),
+                            tooShortGesture = swipeUp(SWIPE_DISTANCE / 2),
+                            testSuffix = "recent apps gesture",
+                        ),
+                    )
+                    .map {
+                        arrayOf(it.recognizer, it.validGestures, it.tooShortGesture, it.testSuffix)
+                    }
+            }
+    }
+
+    class GestureTestData(
+        val recognizer: GestureRecognizer,
+        val validGestures: Set<List<MotionEvent>>,
+        val tooShortGesture: List<MotionEvent>,
+        val testSuffix: String,
+    )
+}
+
+private fun List<MotionEvent>.differentFromAnyOf(validGestures: Set<List<MotionEvent>>): Boolean {
+    // comparing MotionEvents is really hard so let's just compare their positions
+    val positions = this.map { it.x to it.y }
+    val validGesturesPositions = validGestures.map { gesture -> gesture.map { it.x to it.y } }
+    return !validGesturesPositions.contains(positions)
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/view/ViewUtilTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/view/ViewUtilTest.kt
index 3dcb828..72527dd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/view/ViewUtilTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/view/ViewUtilTest.kt
@@ -105,6 +105,20 @@
         assertThat(outRect.top).isEqualTo(VIEW_TOP)
         assertThat(outRect.bottom).isEqualTo(VIEW_BOTTOM)
     }
+
+    @Test
+    fun viewBoundsOnScreen_viewAnchoredAtOriginInWindow() {
+        // view is anchored at 0,0 in its window
+        view.setLeftTopRightBottom(0, 0, VIEW_RIGHT - VIEW_LEFT, VIEW_BOTTOM - VIEW_TOP)
+
+        val outRect = Rect()
+        view.viewBoundsOnScreen(outRect)
+
+        assertThat(outRect.left).isEqualTo(VIEW_LEFT)
+        assertThat(outRect.right).isEqualTo(VIEW_RIGHT)
+        assertThat(outRect.top).isEqualTo(VIEW_TOP)
+        assertThat(outRect.bottom).isEqualTo(VIEW_BOTTOM)
+    }
 }
 
 private const val VIEW_LEFT = 30
diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
index dcb15a7..b2083c2 100644
--- a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
+++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
@@ -213,6 +213,13 @@
         default int getCurrentCardTopPadding() {
             throw new UnsupportedOperationException("Not implemented by " + getClass());
         }
+
+        /**
+         * Set the horizontal paddings for applicable children inside the SmartspaceView.
+         */
+        default void setHorizontalPaddings(int horizontalPadding) {
+            throw new UnsupportedOperationException("Not implemented by " + getClass());
+        }
     }
 
     /** Interface for launching Intents, which can differ on the lockscreen */
diff --git a/packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml b/packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml
index 47641ee..4a14f3b 100644
--- a/packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml
+++ b/packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <item android:color="?androidprv:attr/materialColorSecondaryFixedDim"/>
+    <item android:color="@androidprv:color/materialColorSecondaryFixedDim"/>
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml b/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml
index 5e7cf3e..6a885a7 100644
--- a/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml
+++ b/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml
@@ -19,7 +19,7 @@
     android:color="?attr/wallpaperTextColorSecondary">
     <item android:id="@android:id/background">
         <shape android:shape="rectangle">
-            <solid android:color="?androidprv:attr/materialColorTertiaryFixed"/>
+            <solid android:color="@androidprv:color/materialColorTertiaryFixed"/>
             <corners android:radius="24dp"/>
         </shape>
     </item>
diff --git a/packages/SystemUI/res-keyguard/drawable/progress_bar.xml b/packages/SystemUI/res-keyguard/drawable/progress_bar.xml
index 910a74a..455d9d3 100644
--- a/packages/SystemUI/res-keyguard/drawable/progress_bar.xml
+++ b/packages/SystemUI/res-keyguard/drawable/progress_bar.xml
@@ -26,7 +26,7 @@
             android:layout_height="match_parent"
             android:shape="rectangle">
             <corners android:radius="30dp" />
-            <solid android:color="?androidprv:attr/materialColorSurfaceContainerHighest" />
+            <solid android:color="@androidprv:color/materialColorSurfaceContainerHighest" />
         </shape>
     </item>
     <item
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
index 83736e9..eb9ee03 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
@@ -27,8 +27,8 @@
     android:background="@drawable/kg_bouncer_secondary_button"
     android:drawablePadding="10dp"
     android:drawableStart="@drawable/ic_no_sim"
-    android:drawableTint="?androidprv:attr/materialColorOnSurface"
+    android:drawableTint="@androidprv:color/materialColorOnSurface"
     android:text="@string/disable_carrier_button_text"
-    android:textColor="?androidprv:attr/materialColorOnSurface"
+    android:textColor="@androidprv:color/materialColorOnSurface"
     android:textSize="@dimen/kg_status_line_font_size"
     android:visibility="gone" />
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index ba0d7de..bfb37a0d 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -110,6 +110,7 @@
     <dimen name="below_clock_padding_start">32dp</dimen>
     <dimen name="below_clock_padding_end">16dp</dimen>
     <dimen name="below_clock_padding_start_icons">28dp</dimen>
+    <dimen name="smartspace_padding_horizontal">16dp</dimen>
 
     <!-- Proportion of the screen height to use to set the maximum height of the bouncer to when
          the device is in the DEVICE_POSTURE_HALF_OPENED posture, for the PIN/pattern entry. 0 will
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index da12dd7..b256518e 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -23,13 +23,13 @@
     <style name="Keyguard.TextView" parent="@android:style/Widget.DeviceDefault.TextView">
         <item name="android:textSize">@dimen/kg_status_line_font_size</item>
         <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
     <style name="Keyguard.Bouncer.PrimaryMessage" parent="Theme.SystemUI">
         <item name="android:textSize">18sp</item>
         <item name="android:lineHeight">24dp</item>
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
         <item name="android:singleLine">true</item>
         <item name="android:textAlignment">center</item>
         <item name="android:ellipsize">marquee</item>
@@ -41,10 +41,10 @@
         <item name="android:textAlignment">center</item>
         <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
         <item name="android:ellipsize">end</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
     </style>
     <style name="Keyguard.TextView.EmergencyButton" parent="Theme.SystemUI">
-        <item name="android:textColor">?androidprv:attr/materialColorOnTertiaryFixed</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnTertiaryFixed</item>
         <item name="android:textSize">16sp</item>
         <item name="android:background">@drawable/kg_emergency_button_background</item>
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
diff --git a/packages/SystemUI/res-product/values/strings.xml b/packages/SystemUI/res-product/values/strings.xml
index 42733a2..0c29bb4 100644
--- a/packages/SystemUI/res-product/values/strings.xml
+++ b/packages/SystemUI/res-product/values/strings.xml
@@ -179,6 +179,8 @@
     <!-- Text informing the user that their media is now playing on this tablet device. [CHAR LIMIT=50] -->
     <string name="media_transfer_playing_this_device" product="tablet">Playing on this tablet</string>
 
-
+    <!-- Message shown during shutdown when Find My Device with Dead Battery Finder is active  [CHAR LIMIT=300] -->
+    <string name="finder_active" product="default">You can locate this phone with Find My Device even when powered off</string>
+    <string name="finder_active" product="tablet">You can locate this tablet with Find My Device even when powered off</string>
 
 </resources>
diff --git a/packages/SystemUI/res/color/connected_network_primary_color.xml b/packages/SystemUI/res/color/connected_network_primary_color.xml
index f173c8d..920047a 100644
--- a/packages/SystemUI/res/color/connected_network_primary_color.xml
+++ b/packages/SystemUI/res/color/connected_network_primary_color.xml
@@ -16,5 +16,5 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <item android:color="?androidprv:attr/materialColorOnPrimaryContainer" />
+    <item android:color="@androidprv:color/materialColorOnPrimaryContainer" />
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/disconnected_network_primary_color.xml b/packages/SystemUI/res/color/disconnected_network_primary_color.xml
index 536bf78..f4b19a7 100644
--- a/packages/SystemUI/res/color/disconnected_network_primary_color.xml
+++ b/packages/SystemUI/res/color/disconnected_network_primary_color.xml
@@ -16,5 +16,5 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <item android:color="?androidprv:attr/materialColorPrimaryContainer" />
+    <item android:color="@androidprv:color/materialColorPrimaryContainer" />
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/menu_item_text.xml b/packages/SystemUI/res/color/menu_item_text.xml
index 0d05650..c1c9e2c1 100644
--- a/packages/SystemUI/res/color/menu_item_text.xml
+++ b/packages/SystemUI/res/color/menu_item_text.xml
@@ -17,8 +17,8 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
 
     <item android:state_enabled="false"
-          android:color="?androidprv:attr/materialColorOnSurface"
+          android:color="@androidprv:color/materialColorOnSurface"
           android:alpha="0.38" />
 
-    <item android:color="?androidprv:attr/materialColorOnSurface"/>
+    <item android:color="@androidprv:color/materialColorOnSurface"/>
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/notification_focus_overlay_color.xml b/packages/SystemUI/res/color/notification_focus_overlay_color.xml
index 6a3c7a1..5584363 100644
--- a/packages/SystemUI/res/color/notification_focus_overlay_color.xml
+++ b/packages/SystemUI/res/color/notification_focus_overlay_color.xml
@@ -17,6 +17,6 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <item android:state_focused="true" android:color="?androidprv:attr/materialColorSecondary" />
+    <item android:state_focused="true" android:color="@androidprv:color/materialColorSecondary" />
     <item android:color="@color/transparent" />
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/notification_guts_priority_button_bg_stroke.xml b/packages/SystemUI/res/color/notification_guts_priority_button_bg_stroke.xml
index d1b8a06..e0873b8 100644
--- a/packages/SystemUI/res/color/notification_guts_priority_button_bg_stroke.xml
+++ b/packages/SystemUI/res/color/notification_guts_priority_button_bg_stroke.xml
@@ -17,6 +17,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
     <item android:state_selected="true"
-          android:color="?androidprv:attr/materialColorOnSurfaceVariant" />
+          android:color="@androidprv:color/materialColorOnSurfaceVariant" />
     <item android:color="@color/notification_guts_priority_button_bg_stroke_color" />
 </selector>
diff --git a/packages/SystemUI/res/color/notification_guts_priority_contents.xml b/packages/SystemUI/res/color/notification_guts_priority_contents.xml
index cc8c25a..3b221e7 100644
--- a/packages/SystemUI/res/color/notification_guts_priority_contents.xml
+++ b/packages/SystemUI/res/color/notification_guts_priority_contents.xml
@@ -17,6 +17,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
     <item android:state_selected="true"
-          android:color="?androidprv:attr/materialColorOnSurfaceVariant" />
+          android:color="@androidprv:color/materialColorOnSurfaceVariant" />
     <item android:color="@color/notification_guts_priority_button_content_color" />
 </selector>
diff --git a/packages/SystemUI/res/color/notification_state_color_default.xml b/packages/SystemUI/res/color/notification_state_color_default.xml
index a14a7ad..9d77f60 100644
--- a/packages/SystemUI/res/color/notification_state_color_default.xml
+++ b/packages/SystemUI/res/color/notification_state_color_default.xml
@@ -19,7 +19,7 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
     <!-- Pressed state's alpha is set to 0.00 temporarily until this bug is resolved permanently
     b/313920497 Design intended alpha is 0.15-->
-    <item android:state_pressed="true" android:color="?androidprv:attr/materialColorOnSurface" android:alpha="0.00" />
-    <item android:state_hovered="true" android:color="?androidprv:attr/materialColorOnSurface" android:alpha="0.11" />
+    <item android:state_pressed="true" android:color="@androidprv:color/materialColorOnSurface" android:alpha="0.00" />
+    <item android:state_hovered="true" android:color="@androidprv:color/materialColorOnSurface" android:alpha="0.11" />
     <item android:color="@color/transparent" />
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/qs_dialog_btn_filled_background.xml b/packages/SystemUI/res/color/qs_dialog_btn_filled_background.xml
index 40bab5e..898d589 100644
--- a/packages/SystemUI/res/color/qs_dialog_btn_filled_background.xml
+++ b/packages/SystemUI/res/color/qs_dialog_btn_filled_background.xml
@@ -17,7 +17,7 @@
 <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/materialColorPrimary"
+          android:color="@androidprv:color/materialColorPrimary"
           android:alpha="0.30"/>
-    <item android:color="?androidprv:attr/materialColorPrimary"/>
+    <item android:color="@androidprv:color/materialColorPrimary"/>
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/qs_dialog_btn_filled_large_background.xml b/packages/SystemUI/res/color/qs_dialog_btn_filled_large_background.xml
index f8d4af5..c8ab4ad 100644
--- a/packages/SystemUI/res/color/qs_dialog_btn_filled_large_background.xml
+++ b/packages/SystemUI/res/color/qs_dialog_btn_filled_large_background.xml
@@ -16,7 +16,7 @@
 <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/materialColorPrimaryFixed"
+        android:color="@androidprv:color/materialColorPrimaryFixed"
         android:alpha="0.30"/>
-    <item android:color="?androidprv:attr/materialColorPrimaryFixed"/>
+    <item android:color="@androidprv:color/materialColorPrimaryFixed"/>
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/qs_dialog_btn_filled_large_text.xml b/packages/SystemUI/res/color/qs_dialog_btn_filled_large_text.xml
index faba8fc..60b6245 100644
--- a/packages/SystemUI/res/color/qs_dialog_btn_filled_large_text.xml
+++ b/packages/SystemUI/res/color/qs_dialog_btn_filled_large_text.xml
@@ -16,7 +16,7 @@
 <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/materialColorOnPrimaryFixed"
+        android:color="@androidprv:color/materialColorOnPrimaryFixed"
         android:alpha="0.30"/>
-    <item android:color="?androidprv:attr/materialColorOnPrimaryFixed"/>
+    <item android:color="@androidprv:color/materialColorOnPrimaryFixed"/>
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/qs_dialog_btn_filled_text_color.xml b/packages/SystemUI/res/color/qs_dialog_btn_filled_text_color.xml
index e76ad99..a5497a54 100644
--- a/packages/SystemUI/res/color/qs_dialog_btn_filled_text_color.xml
+++ b/packages/SystemUI/res/color/qs_dialog_btn_filled_text_color.xml
@@ -17,7 +17,7 @@
 <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/materialColorOnPrimary"
+          android:color="@androidprv:color/materialColorOnPrimary"
           android:alpha="0.30"/>
-    <item android:color="?androidprv:attr/materialColorOnPrimary"/>
+    <item android:color="@androidprv:color/materialColorOnPrimary"/>
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/qs_dialog_btn_outline.xml b/packages/SystemUI/res/color/qs_dialog_btn_outline.xml
index 1adfe5b..7ef7e06 100644
--- a/packages/SystemUI/res/color/qs_dialog_btn_outline.xml
+++ b/packages/SystemUI/res/color/qs_dialog_btn_outline.xml
@@ -17,7 +17,7 @@
 <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/materialColorPrimary"
+        android:color="@androidprv:color/materialColorPrimary"
         android:alpha="0.30"/>
-    <item android:color="?androidprv:attr/materialColorPrimary"/>
+    <item android:color="@androidprv:color/materialColorPrimary"/>
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/qs_dialog_btn_outline_text.xml b/packages/SystemUI/res/color/qs_dialog_btn_outline_text.xml
index 5dc994f23..f139008 100644
--- a/packages/SystemUI/res/color/qs_dialog_btn_outline_text.xml
+++ b/packages/SystemUI/res/color/qs_dialog_btn_outline_text.xml
@@ -17,7 +17,7 @@
 <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:color="@androidprv:color/materialColorOnSurface"
         android:alpha="0.30"/>
-    <item android:color="?androidprv:attr/materialColorOnSurface"/>
+    <item android:color="@androidprv:color/materialColorOnSurface"/>
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/remote_input_hint.xml b/packages/SystemUI/res/color/remote_input_hint.xml
index 0d90ee6..75d2bb8 100644
--- a/packages/SystemUI/res/color/remote_input_hint.xml
+++ b/packages/SystemUI/res/color/remote_input_hint.xml
@@ -16,5 +16,5 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <item android:color="?androidprv:attr/materialColorOnSurfaceVariant" android:alpha=".6" />
+    <item android:color="@androidprv:color/materialColorOnSurfaceVariant" android:alpha=".6" />
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/remote_input_send.xml b/packages/SystemUI/res/color/remote_input_send.xml
index 0acc66b..4c61c0c 100644
--- a/packages/SystemUI/res/color/remote_input_send.xml
+++ b/packages/SystemUI/res/color/remote_input_send.xml
@@ -17,6 +17,6 @@
 
 <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/materialColorPrimary" android:alpha=".3" />
-    <item android:color="?androidprv:attr/materialColorPrimary" />
+    <item android:state_enabled="false" android:color="@androidprv:color/materialColorPrimary" android:alpha=".3" />
+    <item android:color="@androidprv:color/materialColorPrimary" />
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/remote_input_text.xml b/packages/SystemUI/res/color/remote_input_text.xml
index bf2c198..2ec09cd 100644
--- a/packages/SystemUI/res/color/remote_input_text.xml
+++ b/packages/SystemUI/res/color/remote_input_text.xml
@@ -17,6 +17,6 @@
 
 <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/materialColorOnSurfaceVariant" android:alpha=".6" />
-    <item android:color="?androidprv:attr/materialColorOnSurfaceVariant" />
+    <item android:state_enabled="false" android:color="@androidprv:color/materialColorOnSurfaceVariant" android:alpha=".6" />
+    <item android:color="@androidprv:color/materialColorOnSurfaceVariant" />
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/screenshare_options_spinner_background.xml b/packages/SystemUI/res/color/screenshare_options_spinner_background.xml
index 922813dc..f3059f6 100644
--- a/packages/SystemUI/res/color/screenshare_options_spinner_background.xml
+++ b/packages/SystemUI/res/color/screenshare_options_spinner_background.xml
@@ -17,6 +17,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
     <item android:state_hovered="false" android:state_focused="false" android:color="@android:color/transparent" />
-    <item android:state_focused="true" android:color="?androidprv:attr/materialColorOnSurface" android:alpha=".1" />
-    <item android:state_hovered="true" android:color="?androidprv:attr/materialColorOnSurface" android:alpha=".08" />
+    <item android:state_focused="true" android:color="@androidprv:color/materialColorOnSurface" android:alpha=".1" />
+    <item android:state_hovered="true" android:color="@androidprv:color/materialColorOnSurface" android:alpha=".08" />
 </selector>
diff --git a/packages/SystemUI/res/color/slider_active_track_color.xml b/packages/SystemUI/res/color/slider_active_track_color.xml
index a5aa58d..8ba5e49 100644
--- a/packages/SystemUI/res/color/slider_active_track_color.xml
+++ b/packages/SystemUI/res/color/slider_active_track_color.xml
@@ -14,6 +14,6 @@
   ~ 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:color="?androidprv:attr/materialColorPrimary" android:state_enabled="true" />
-    <item android:color="?androidprv:attr/materialColorSurfaceContainerHighest" />
+    <item android:color="@androidprv:color/materialColorPrimary" android:state_enabled="true" />
+    <item android:color="@androidprv:color/materialColorSurfaceContainerHighest" />
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/slider_inactive_track_color.xml b/packages/SystemUI/res/color/slider_inactive_track_color.xml
index 89aef77..7980f80 100644
--- a/packages/SystemUI/res/color/slider_inactive_track_color.xml
+++ b/packages/SystemUI/res/color/slider_inactive_track_color.xml
@@ -14,6 +14,6 @@
   ~ 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:color="?androidprv:attr/materialColorSurfaceContainerHighest" android:state_enabled="true" />
-    <item android:color="?androidprv:attr/materialColorPrimary" />
+    <item android:color="@androidprv:color/materialColorSurfaceContainerHighest" android:state_enabled="true" />
+    <item android:color="@androidprv:color/materialColorPrimary" />
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/slider_thumb_color.xml b/packages/SystemUI/res/color/slider_thumb_color.xml
index 5206049..8a98902 100644
--- a/packages/SystemUI/res/color/slider_thumb_color.xml
+++ b/packages/SystemUI/res/color/slider_thumb_color.xml
@@ -15,6 +15,6 @@
   -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <item android:color="?androidprv:attr/materialColorSurfaceContainerHighest" android:state_enabled="false" />
-    <item android:color="?androidprv:attr/materialColorPrimary" />
+    <item android:color="@androidprv:color/materialColorSurfaceContainerHighest" android:state_enabled="false" />
+    <item android:color="@androidprv:color/materialColorPrimary" />
 </selector>
diff --git a/packages/SystemUI/res/drawable-night/privacy_dialog_expand_toggle_down.xml b/packages/SystemUI/res/drawable-night/privacy_dialog_expand_toggle_down.xml
index 16076b1..d54164b 100644
--- a/packages/SystemUI/res/drawable-night/privacy_dialog_expand_toggle_down.xml
+++ b/packages/SystemUI/res/drawable-night/privacy_dialog_expand_toggle_down.xml
@@ -24,8 +24,8 @@
     android:viewportHeight="24">
   <path
       android:pathData="M0,12C0,5.373 5.373,0 12,0C18.627,0 24,5.373 24,12C24,18.627 18.627,24 12,24C5.373,24 0,18.627 0,12Z"
-      android:fillColor="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+      android:fillColor="@androidprv:color/materialColorSurfaceContainerHigh"/>
   <path
       android:pathData="M7.607,9.059L6.667,9.999L12,15.332L17.333,9.999L16.393,9.059L12,13.445"
-      android:fillColor="?androidprv:attr/materialColorOnSurface"/>
+      android:fillColor="@androidprv:color/materialColorOnSurface"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable-night/privacy_dialog_expand_toggle_up.xml b/packages/SystemUI/res/drawable-night/privacy_dialog_expand_toggle_up.xml
index 309770d..81184a1 100644
--- a/packages/SystemUI/res/drawable-night/privacy_dialog_expand_toggle_up.xml
+++ b/packages/SystemUI/res/drawable-night/privacy_dialog_expand_toggle_up.xml
@@ -24,8 +24,8 @@
     android:viewportHeight="24">
   <path
       android:pathData="M0,12C0,5.3726 5.3726,0 12,0C18.6274,0 24,5.3726 24,12C24,18.6274 18.6274,24 12,24C5.3726,24 0,18.6274 0,12Z"
-      android:fillColor="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+      android:fillColor="@androidprv:color/materialColorSurfaceContainerHigh"/>
   <path
       android:pathData="M16.3934,14.9393L17.3334,13.9993L12.0001,8.666L6.6667,13.9993L7.6068,14.9393L12.0001,10.5527"
-      android:fillColor="?androidprv:attr/materialColorOnSurface"/>
+      android:fillColor="@androidprv:color/materialColorOnSurface"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/action_chip_background.xml b/packages/SystemUI/res/drawable/action_chip_background.xml
index 9492472..0958c84 100644
--- a/packages/SystemUI/res/drawable/action_chip_background.xml
+++ b/packages/SystemUI/res/drawable/action_chip_background.xml
@@ -20,7 +20,7 @@
     android:color="@color/overlay_button_ripple">
     <item android:id="@android:id/background">
         <shape android:shape="rectangle">
-            <solid android:color="?androidprv:attr/materialColorSecondary"/>
+            <solid android:color="@androidprv:color/materialColorSecondary"/>
             <corners android:radius="@dimen/overlay_button_corner_radius"/>
         </shape>
     </item>
diff --git a/packages/SystemUI/res/drawable/action_chip_container_background.xml b/packages/SystemUI/res/drawable/action_chip_container_background.xml
index 2ee2710..5aced9d 100644
--- a/packages/SystemUI/res/drawable/action_chip_container_background.xml
+++ b/packages/SystemUI/res/drawable/action_chip_container_background.xml
@@ -18,6 +18,6 @@
     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="?androidprv:attr/materialColorSurfaceBright"/>
+    <solid android:color="@androidprv:color/materialColorSurfaceBright"/>
     <corners android:radius="@dimen/overlay_action_container_corner_radius"/>
 </shape>
diff --git a/packages/SystemUI/res/drawable/biometric_prompt_vertical_list_content_view_background.xml b/packages/SystemUI/res/drawable/biometric_prompt_vertical_list_content_view_background.xml
index fdafe6d..63d0268 100644
--- a/packages/SystemUI/res/drawable/biometric_prompt_vertical_list_content_view_background.xml
+++ b/packages/SystemUI/res/drawable/biometric_prompt_vertical_list_content_view_background.xml
@@ -18,6 +18,6 @@
     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="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+    <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh"/>
     <corners android:radius="@dimen/biometric_prompt_content_corner_radius"/>
 </shape>
diff --git a/packages/SystemUI/res/drawable/brightness_bar.xml b/packages/SystemUI/res/drawable/brightness_bar.xml
index 3d1c1fb..a32496b 100644
--- a/packages/SystemUI/res/drawable/brightness_bar.xml
+++ b/packages/SystemUI/res/drawable/brightness_bar.xml
@@ -21,7 +21,7 @@
         android:viewportHeight="48">
 <path
     android:pathData="M2,22L302,22A2,2 0,0 1,304 24L304,24A2,2 0,0 1,302 26L2,26A2,2 0,0 1,0 24L0,24A2,2 0,0 1,2 22z"
-    android:fillColor="?androidprv:attr/customColorShadeInactive"/>
+    android:fillColor="@androidprv:color/customColorShadeInactive"/>
 <path
     android:pathData="M24,0L205.71,0A24,24 0,0 1,229.71 24L229.71,24A24,24 0,0 1,205.71 48L24,48A24,24 0,0 1,0 24L0,24A24,24 0,0 1,24 0z"
     android:fillColor="?attr/shadeActive"/>
diff --git a/packages/SystemUI/res/drawable/brightness_progress_drawable.xml b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
index ec15b10..88d3ecb 100644
--- a/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
+++ b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
@@ -25,7 +25,7 @@
             <shape>
                 <size android:height="@dimen/rounded_slider_track_width" />
                 <corners android:radius="@dimen/rounded_slider_track_corner_radius" />
-                <solid android:color="?androidprv:attr/customColorShadeInactive" />
+                <solid android:color="@androidprv:color/customColorShadeInactive" />
             </shape>
         </inset>
     </item>
diff --git a/packages/SystemUI/res/drawable/brightness_slider_focus_bg.xml b/packages/SystemUI/res/drawable/brightness_slider_focus_bg.xml
index 22406ec..5462898 100644
--- a/packages/SystemUI/res/drawable/brightness_slider_focus_bg.xml
+++ b/packages/SystemUI/res/drawable/brightness_slider_focus_bg.xml
@@ -22,7 +22,7 @@
         <inset android:inset="-5dp">
             <shape>
                 <corners android:radius="16dp"/>
-                <stroke android:width="3dp" android:color="?androidprv:attr/materialColorSecondaryFixed"/>
+                <stroke android:width="3dp" android:color="@androidprv:color/materialColorSecondaryFixed"/>
             </shape>
         </inset>
     </item>
diff --git a/packages/SystemUI/res/drawable/chipbar_background.xml b/packages/SystemUI/res/drawable/chipbar_background.xml
index 7530f5b..15c9fcb 100644
--- a/packages/SystemUI/res/drawable/chipbar_background.xml
+++ b/packages/SystemUI/res/drawable/chipbar_background.xml
@@ -17,6 +17,6 @@
 <shape
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <solid android:color="?androidprv:attr/materialColorSecondaryFixed" />
+    <solid android:color="@androidprv:color/materialColorSecondaryFixed" />
     <corners android:radius="32dp" />
 </shape>
diff --git a/packages/SystemUI/res/drawable/chipbar_end_button_background.xml b/packages/SystemUI/res/drawable/chipbar_end_button_background.xml
index a3832ee..fcf5b30 100644
--- a/packages/SystemUI/res/drawable/chipbar_end_button_background.xml
+++ b/packages/SystemUI/res/drawable/chipbar_end_button_background.xml
@@ -20,7 +20,7 @@
     android:color="?android:textColorPrimary">
     <item android:id="@android:id/background">
         <shape>
-            <solid android:color="?androidprv:attr/materialColorPrimaryFixedDim"/>
+            <solid android:color="@androidprv:color/materialColorPrimaryFixedDim"/>
             <corners android:radius="24dp" />
         </shape>
     </item>
diff --git a/packages/SystemUI/res/drawable/contextual_edu_dialog_bg.xml b/packages/SystemUI/res/drawable/contextual_edu_dialog_bg.xml
index d7000d7..b891163 100644
--- a/packages/SystemUI/res/drawable/contextual_edu_dialog_bg.xml
+++ b/packages/SystemUI/res/drawable/contextual_edu_dialog_bg.xml
@@ -19,6 +19,6 @@
     android:insetBottom="@dimen/contextual_edu_dialog_elevation">
     <shape>
         <corners android:radius="28dp" />
-        <solid android:color="?androidprv:attr/materialColorTertiaryFixed" />
+        <solid android:color="@androidprv:color/materialColorTertiaryFixed" />
     </shape>
 </inset>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/hearing_devices_spinner_popup_background.xml b/packages/SystemUI/res/drawable/hearing_devices_spinner_popup_background.xml
index f35975e..5ddc860 100644
--- a/packages/SystemUI/res/drawable/hearing_devices_spinner_popup_background.xml
+++ b/packages/SystemUI/res/drawable/hearing_devices_spinner_popup_background.xml
@@ -18,5 +18,5 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:shape="rectangle">
     <corners android:radius="@dimen/hearing_devices_preset_spinner_background_radius"/>
-    <solid android:color="?androidprv:attr/materialColorSurfaceContainer" />
+    <solid android:color="@androidprv:color/materialColorSurfaceContainer" />
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_check_circle_filled_24dp.xml b/packages/SystemUI/res/drawable/ic_check_circle_filled_24dp.xml
index 16e2a3d..307f7eb 100644
--- a/packages/SystemUI/res/drawable/ic_check_circle_filled_24dp.xml
+++ b/packages/SystemUI/res/drawable/ic_check_circle_filled_24dp.xml
@@ -18,7 +18,7 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:width="24dp"
     android:height="24dp"
-    android:tint="?androidprv:attr/materialColorPrimary"
+    android:tint="@androidprv:color/materialColorPrimary"
     android:viewportHeight="24"
     android:viewportWidth="24">
     <path
diff --git a/packages/SystemUI/res/drawable/ic_circle_outline_24dp.xml b/packages/SystemUI/res/drawable/ic_circle_outline_24dp.xml
index 82fa4f0..8304fd5 100644
--- a/packages/SystemUI/res/drawable/ic_circle_outline_24dp.xml
+++ b/packages/SystemUI/res/drawable/ic_circle_outline_24dp.xml
@@ -18,7 +18,7 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:width="24dp"
     android:height="24dp"
-    android:tint="?androidprv:attr/materialColorPrimary"
+    android:tint="@androidprv:color/materialColorPrimary"
     android:viewportHeight="24"
     android:viewportWidth="24">
     <path
diff --git a/packages/SystemUI/res/drawable/ic_screensaver_auto.xml b/packages/SystemUI/res/drawable/ic_screensaver_auto.xml
new file mode 100644
index 0000000..7cccff6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_screensaver_auto.xml
@@ -0,0 +1,26 @@
+<?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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="960"
+    android:viewportHeight="960"
+    android:tint="?attr/colorControlNormal">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M160,240Q160,240 160,240Q160,240 160,240L160,720Q160,720 160,720Q160,720 160,720L160,720Q160,720 160,720Q160,720 160,720L160,240Q160,240 160,240Q160,240 160,240L160,240Q160,240 160,240Q160,240 160,240Q160,240 160,240Q160,240 160,240ZM160,800Q127,800 103.5,776.5Q80,753 80,720L80,240Q80,207 103.5,183.5Q127,160 160,160L440,160Q440,179 440,199Q440,219 440,240L160,240Q160,240 160,240Q160,240 160,240L160,720Q160,720 160,720Q160,720 160,720L800,720Q800,720 800,720Q800,720 800,720L800,480Q823,480 843,480Q863,480 880,480L880,720Q880,753 856.5,776.5Q833,800 800,800L160,800ZM700,480Q700,388 636,324Q572,260 480,260Q572,260 636,196Q700,132 700,40Q700,132 764,196Q828,260 920,260Q828,260 764,324Q700,388 700,480Z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_shortcutlist_search.xml b/packages/SystemUI/res/drawable/ic_shortcutlist_search.xml
index 0406f0e..ddff884 100644
--- a/packages/SystemUI/res/drawable/ic_shortcutlist_search.xml
+++ b/packages/SystemUI/res/drawable/ic_shortcutlist_search.xml
@@ -19,7 +19,7 @@
         android:height="24dp"
         android:viewportWidth="48"
         android:viewportHeight="48"
-        android:tint="?androidprv:attr/materialColorOnSurfaceVariant">
+        android:tint="@androidprv:color/materialColorOnSurfaceVariant">
     <path
         android:fillColor="@android:color/white"
         android:strokeColor="@android:color/white"
diff --git a/packages/SystemUI/res/drawable/immersive_cling_bg.xml b/packages/SystemUI/res/drawable/immersive_cling_bg.xml
index de29c32..b28a423 100644
--- a/packages/SystemUI/res/drawable/immersive_cling_bg.xml
+++ b/packages/SystemUI/res/drawable/immersive_cling_bg.xml
@@ -20,5 +20,5 @@
     <corners
         android:bottomLeftRadius="28dp"
         android:bottomRightRadius="28dp"/>
-    <solid android:color="?androidprv:attr/materialColorSurfaceContainer" />
+    <solid android:color="@androidprv:color/materialColorSurfaceContainer" />
 </shape>
diff --git a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
index 32dc4b3..6ad46d8 100644
--- a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
+++ b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
@@ -20,7 +20,7 @@
     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="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+  <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh"/>
   <size
       android:width="@dimen/keyguard_affordance_fixed_width"
       android:height="@dimen/keyguard_affordance_fixed_height"/>
diff --git a/packages/SystemUI/res/drawable/keyguard_settings_popup_menu_background.xml b/packages/SystemUI/res/drawable/keyguard_settings_popup_menu_background.xml
index fe76ba7..fab0cc2 100644
--- a/packages/SystemUI/res/drawable/keyguard_settings_popup_menu_background.xml
+++ b/packages/SystemUI/res/drawable/keyguard_settings_popup_menu_background.xml
@@ -26,7 +26,7 @@
     </item>
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="?androidprv:attr/materialColorSecondaryFixed" />
+            <solid android:color="@androidprv:color/materialColorSecondaryFixed" />
             <corners android:radius="@dimen/keyguard_affordance_fixed_radius" />
         </shape>
     </item>
diff --git a/packages/SystemUI/res/drawable/notif_footer_btn_background.xml b/packages/SystemUI/res/drawable/notif_footer_btn_background.xml
index b959737..1d5e09d 100644
--- a/packages/SystemUI/res/drawable/notif_footer_btn_background.xml
+++ b/packages/SystemUI/res/drawable/notif_footer_btn_background.xml
@@ -26,7 +26,7 @@
                 <padding
                     android:left="20dp"
                     android:right="20dp" />
-                <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh" />
+                <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh" />
             </shape>
         </inset>
     </item>
diff --git a/packages/SystemUI/res/drawable/notification_guts_bg.xml b/packages/SystemUI/res/drawable/notification_guts_bg.xml
index 84e2231..200976b 100644
--- a/packages/SystemUI/res/drawable/notification_guts_bg.xml
+++ b/packages/SystemUI/res/drawable/notification_guts_bg.xml
@@ -17,7 +17,7 @@
 
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh" />
+    <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh" />
     <!--The radius is 1dp smaller than the notification one, to avoid aliasing bugs on the corners -->
     <corners android:radius="1dp" />
 </shape>
diff --git a/packages/SystemUI/res/drawable/notification_material_bg.xml b/packages/SystemUI/res/drawable/notification_material_bg.xml
index 715be07..db3b969 100644
--- a/packages/SystemUI/res/drawable/notification_material_bg.xml
+++ b/packages/SystemUI/res/drawable/notification_material_bg.xml
@@ -20,7 +20,7 @@
         android:color="?android:attr/colorControlHighlight">
     <item>
         <shape>
-            <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh" />
+            <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh" />
         </shape>
     </item>
     <item>
diff --git a/packages/SystemUI/res/drawable/overlay_border.xml b/packages/SystemUI/res/drawable/overlay_border.xml
index a59f923..381849b 100644
--- a/packages/SystemUI/res/drawable/overlay_border.xml
+++ b/packages/SystemUI/res/drawable/overlay_border.xml
@@ -18,6 +18,6 @@
     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="?androidprv:attr/materialColorSurfaceBright"/>
+    <solid android:color="@androidprv:color/materialColorSurfaceBright"/>
     <corners android:radius="16dp"/>
 </shape>
diff --git a/packages/SystemUI/res/drawable/privacy_dialog_expand_toggle_down.xml b/packages/SystemUI/res/drawable/privacy_dialog_expand_toggle_down.xml
index f8b99f4..299b4c9 100644
--- a/packages/SystemUI/res/drawable/privacy_dialog_expand_toggle_down.xml
+++ b/packages/SystemUI/res/drawable/privacy_dialog_expand_toggle_down.xml
@@ -23,8 +23,8 @@
     android:viewportHeight="24">
   <path
       android:pathData="M0,12C0,5.373 5.373,0 12,0C18.627,0 24,5.373 24,12C24,18.627 18.627,24 12,24C5.373,24 0,18.627 0,12Z"
-      android:fillColor="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+      android:fillColor="@androidprv:color/materialColorSurfaceContainerHigh"/>
   <path
       android:pathData="M7.607,9.059L6.667,9.999L12,15.332L17.333,9.999L16.393,9.059L12,13.445"
-      android:fillColor="?androidprv:attr/materialColorOnSurface"/>
+      android:fillColor="@androidprv:color/materialColorOnSurface"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/privacy_dialog_expand_toggle_up.xml b/packages/SystemUI/res/drawable/privacy_dialog_expand_toggle_up.xml
index ae60d51..68e73e9 100644
--- a/packages/SystemUI/res/drawable/privacy_dialog_expand_toggle_up.xml
+++ b/packages/SystemUI/res/drawable/privacy_dialog_expand_toggle_up.xml
@@ -23,8 +23,8 @@
     android:viewportHeight="24">
   <path
       android:pathData="M0,12C0,5.3726 5.3726,0 12,0C18.6274,0 24,5.3726 24,12C24,18.6274 18.6274,24 12,24C5.3726,24 0,18.6274 0,12Z"
-      android:fillColor="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+      android:fillColor="@androidprv:color/materialColorSurfaceContainerHigh"/>
   <path
       android:pathData="M16.3934,14.9393L17.3334,13.9993L12.0001,8.666L6.6667,13.9993L7.6068,14.9393L12.0001,10.5527"
-      android:fillColor="?androidprv:attr/materialColorOnSurface"/>
+      android:fillColor="@androidprv:color/materialColorOnSurface"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/qs_hearing_devices_related_tools_background.xml b/packages/SystemUI/res/drawable/qs_hearing_devices_related_tools_background.xml
index 3c16684..e90473b 100644
--- a/packages/SystemUI/res/drawable/qs_hearing_devices_related_tools_background.xml
+++ b/packages/SystemUI/res/drawable/qs_hearing_devices_related_tools_background.xml
@@ -21,7 +21,7 @@
     android:color="?android:attr/colorControlHighlight">
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="?androidprv:attr/materialColorPrimaryContainer"/>
+            <solid android:color="@androidprv:color/materialColorPrimaryContainer"/>
             <corners android:radius="@dimen/hearing_devices_preset_spinner_background_radius"/>
         </shape>
     </item>
diff --git a/packages/SystemUI/res/drawable/qs_tile_focused_background.xml b/packages/SystemUI/res/drawable/qs_tile_focused_background.xml
index 33f0d02..cdf6a1a 100644
--- a/packages/SystemUI/res/drawable/qs_tile_focused_background.xml
+++ b/packages/SystemUI/res/drawable/qs_tile_focused_background.xml
@@ -21,6 +21,6 @@
         <corners android:radius="30dp" />
         <stroke
             android:width="3dp"
-            android:color="?androidprv:attr/materialColorSecondaryFixed" />
+            android:color="@androidprv:color/materialColorSecondaryFixed" />
     </shape>
 </inset>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/remote_input_view_text_bg.xml b/packages/SystemUI/res/drawable/remote_input_view_text_bg.xml
index 45d1a53..01ecbcf 100644
--- a/packages/SystemUI/res/drawable/remote_input_view_text_bg.xml
+++ b/packages/SystemUI/res/drawable/remote_input_view_text_bg.xml
@@ -17,10 +17,10 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:shape="rectangle">
 
-    <solid android:color="?androidprv:attr/materialColorSurfaceDim" />
+    <solid android:color="@androidprv:color/materialColorSurfaceDim" />
     <stroke
         android:width="@dimen/remote_input_view_text_stroke"
-        android:color="?androidprv:attr/materialColorPrimary"/>
+        android:color="@androidprv:color/materialColorPrimary"/>
     <padding
         android:bottom="0dp"
         android:left="12dp"
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 321a04a..323cb77 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/materialColorSurfaceContainer" />
+    <solid android:color="@androidprv:color/materialColorSurfaceContainer" />
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/screenshot_edit_background.xml b/packages/SystemUI/res/drawable/screenshot_edit_background.xml
index 07e5aff..ef1c30f 100644
--- a/packages/SystemUI/res/drawable/screenshot_edit_background.xml
+++ b/packages/SystemUI/res/drawable/screenshot_edit_background.xml
@@ -20,7 +20,7 @@
         android:color="@color/overlay_button_ripple">
     <item android:id="@android:id/background">
         <shape android:shape="rectangle">
-            <solid android:color="?androidprv:attr/materialColorSecondaryFixedDim"/>
+            <solid android:color="@androidprv:color/materialColorSecondaryFixedDim"/>
             <corners android:radius="16dp"/>
         </shape>
     </item>
diff --git a/packages/SystemUI/res/drawable/settingslib_switch_bar_bg_on.xml b/packages/SystemUI/res/drawable/settingslib_switch_bar_bg_on.xml
index fab2d8d..2063d9f 100644
--- a/packages/SystemUI/res/drawable/settingslib_switch_bar_bg_on.xml
+++ b/packages/SystemUI/res/drawable/settingslib_switch_bar_bg_on.xml
@@ -20,7 +20,7 @@
     android:color="?android:attr/colorControlHighlight">
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="?androidprv:attr/materialColorPrimaryContainer"/>
+            <solid android:color="@androidprv:color/materialColorPrimaryContainer"/>
             <corners android:radius="@dimen/settingslib_switch_bar_radius"/>
         </shape>
     </item>
diff --git a/packages/SystemUI/res/drawable/settingslib_thumb_on.xml b/packages/SystemUI/res/drawable/settingslib_thumb_on.xml
index e316a93..70a1e84 100644
--- a/packages/SystemUI/res/drawable/settingslib_thumb_on.xml
+++ b/packages/SystemUI/res/drawable/settingslib_thumb_on.xml
@@ -24,7 +24,7 @@
             <size
                 android:height="@dimen/settingslib_switch_thumb_size"
                 android:width="@dimen/settingslib_switch_thumb_size"/>
-            <solid android:color="?androidprv:attr/materialColorOnPrimary"/>
+            <solid android:color="@androidprv:color/materialColorOnPrimary"/>
         </shape>
     </item>
 </layer-list>
diff --git a/packages/SystemUI/res/drawable/settingslib_track_on_background.xml b/packages/SystemUI/res/drawable/settingslib_track_on_background.xml
index e2e6468..e3476a4 100644
--- a/packages/SystemUI/res/drawable/settingslib_track_on_background.xml
+++ b/packages/SystemUI/res/drawable/settingslib_track_on_background.xml
@@ -22,6 +22,6 @@
     android:height="@dimen/settingslib_switch_track_height">
     <padding android:left="@dimen/settingslib_switch_thumb_margin"
              android:right="@dimen/settingslib_switch_thumb_margin"/>
-    <solid android:color="?androidprv:attr/materialColorPrimary"/>
+    <solid android:color="@androidprv:color/materialColorPrimary"/>
     <corners android:radius="@dimen/settingslib_switch_track_radius"/>
 </shape>
diff --git a/packages/SystemUI/res/drawable/shelf_action_chip_background.xml b/packages/SystemUI/res/drawable/shelf_action_chip_background.xml
index 63600be..faa3d68 100644
--- a/packages/SystemUI/res/drawable/shelf_action_chip_background.xml
+++ b/packages/SystemUI/res/drawable/shelf_action_chip_background.xml
@@ -20,7 +20,7 @@
     android:color="@color/overlay_button_ripple">
     <item android:id="@android:id/background">
         <shape android:shape="rectangle">
-            <solid android:color="?androidprv:attr/materialColorSecondary"/>
+            <solid android:color="@androidprv:color/materialColorSecondary"/>
             <corners android:radius="10000dp"/>  <!-- fully-rounded radius -->
         </shape>
     </item>
diff --git a/packages/SystemUI/res/drawable/shelf_action_chip_container_background.xml b/packages/SystemUI/res/drawable/shelf_action_chip_container_background.xml
index ad6c154..82f034b 100644
--- a/packages/SystemUI/res/drawable/shelf_action_chip_container_background.xml
+++ b/packages/SystemUI/res/drawable/shelf_action_chip_container_background.xml
@@ -21,7 +21,7 @@
     <shape
         xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
         android:shape="rectangle">
-        <solid android:color="?androidprv:attr/materialColorSurfaceBright"/>
+        <solid android:color="@androidprv:color/materialColorSurfaceBright"/>
         <corners android:radius="10000dp"/>  <!-- fully-rounded radius -->
     </shape>
 </inset>
\ 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 2e2d9b9..b6a14c8 100644
--- a/packages/SystemUI/res/drawable/shortcut_button_colored.xml
+++ b/packages/SystemUI/res/drawable/shortcut_button_colored.xml
@@ -22,7 +22,7 @@
         <item>
             <shape android:shape="rectangle">
               <corners android:radius="@dimen/ksh_button_corner_radius"/>
-                <solid android:color="?androidprv:attr/materialColorSurfaceBright"/>
+                <solid android:color="@androidprv:color/materialColorSurfaceBright"/>
             </shape>
         </item>
     </ripple>
diff --git a/packages/SystemUI/res/drawable/shortcut_button_focus_colored.xml b/packages/SystemUI/res/drawable/shortcut_button_focus_colored.xml
index 5b88bb9..2b95a94 100644
--- a/packages/SystemUI/res/drawable/shortcut_button_focus_colored.xml
+++ b/packages/SystemUI/res/drawable/shortcut_button_focus_colored.xml
@@ -22,7 +22,7 @@
         <item>
             <shape android:shape="rectangle">
               <corners android:radius="@dimen/ksh_button_corner_radius"/>
-                <solid android:color="?androidprv:attr/materialColorPrimary"/>
+                <solid android:color="@androidprv:color/materialColorPrimary"/>
             </shape>
         </item>
     </ripple>
diff --git a/packages/SystemUI/res/drawable/shortcut_search_background.xml b/packages/SystemUI/res/drawable/shortcut_search_background.xml
index d6847f0..07e5b3d 100644
--- a/packages/SystemUI/res/drawable/shortcut_search_background.xml
+++ b/packages/SystemUI/res/drawable/shortcut_search_background.xml
@@ -19,7 +19,7 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="?androidprv:attr/materialColorSurfaceBright" />
+            <solid android:color="@androidprv:color/materialColorSurfaceBright" />
             <corners android:radius="@dimen/ksh_search_box_corner_radius" />
         </shape>
     </item>
diff --git a/packages/SystemUI/res/drawable/shortcut_search_cancel_button.xml b/packages/SystemUI/res/drawable/shortcut_search_cancel_button.xml
index 2675906..6390c11d 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/materialColorSurfaceBright"/>
+      <solid android:color="@androidprv:color/materialColorSurfaceBright"/>
     </shape>
   </item>
 </ripple>
diff --git a/packages/SystemUI/res/drawable/status_bar_notification_section_header_clear_btn.xml b/packages/SystemUI/res/drawable/status_bar_notification_section_header_clear_btn.xml
index 06bed00..42a5d30 100644
--- a/packages/SystemUI/res/drawable/status_bar_notification_section_header_clear_btn.xml
+++ b/packages/SystemUI/res/drawable/status_bar_notification_section_header_clear_btn.xml
@@ -21,6 +21,6 @@
     android:viewportWidth="40"
     android:viewportHeight="40">
     <path
-        android:fillColor="?androidprv:attr/materialColorOnSurfaceVariant"
+        android:fillColor="@androidprv:color/materialColorOnSurfaceVariant"
         android:pathData="M24.6667 16.2733L23.7267 15.3333L20 19.06L16.2734 15.3333L15.3334 16.2733L19.06 20L15.3334 23.7267L16.2734 24.6667L20 20.94L23.7267 24.6667L24.6667 23.7267L20.94 20L24.6667 16.2733Z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/volume_background_top.xml b/packages/SystemUI/res/drawable/volume_background_top.xml
index 132572a..7185d03 100644
--- a/packages/SystemUI/res/drawable/volume_background_top.xml
+++ b/packages/SystemUI/res/drawable/volume_background_top.xml
@@ -17,7 +17,7 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
     <item>
         <shape>
-            <solid android:color="?androidprv:attr/materialColorSurface" />
+            <solid android:color="@androidprv:color/materialColorSurface" />
             <corners android:topLeftRadius="@dimen/volume_dialog_background_corner_radius"
                 android:topRightRadius="@dimen/volume_dialog_background_corner_radius"/>
         </shape>
diff --git a/packages/SystemUI/res/drawable/volume_dialog_background.xml b/packages/SystemUI/res/drawable/volume_dialog_background.xml
index 7d7498f..25d78e3 100644
--- a/packages/SystemUI/res/drawable/volume_dialog_background.xml
+++ b/packages/SystemUI/res/drawable/volume_dialog_background.xml
@@ -18,5 +18,5 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:shape="rectangle">
     <corners android:radius="@dimen/volume_dialog_background_corner_radius" />
-    <solid android:color="?androidprv:attr/materialColorSurface" />
+    <solid android:color="@androidprv:color/materialColorSurface" />
 </shape>
diff --git a/packages/SystemUI/res/drawable/volume_dialog_background_small_radius.xml b/packages/SystemUI/res/drawable/volume_dialog_background_small_radius.xml
index 7d79496..9026d64 100644
--- a/packages/SystemUI/res/drawable/volume_dialog_background_small_radius.xml
+++ b/packages/SystemUI/res/drawable/volume_dialog_background_small_radius.xml
@@ -17,5 +17,5 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:shape="rectangle">
     <corners android:radius="@dimen/volume_dialog_background_square_corner_radius" />
-    <solid android:color="?androidprv:attr/materialColorSurface" />
+    <solid android:color="@androidprv:color/materialColorSurface" />
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/volume_drawer_selection_bg.xml b/packages/SystemUI/res/drawable/volume_drawer_selection_bg.xml
index 131201e..555eebd 100644
--- a/packages/SystemUI/res/drawable/volume_drawer_selection_bg.xml
+++ b/packages/SystemUI/res/drawable/volume_drawer_selection_bg.xml
@@ -19,6 +19,6 @@
     <size
         android:height="@dimen/volume_dialog_ringer_drawer_button_size"
         android:width="@dimen/volume_dialog_ringer_drawer_button_size" />
-    <solid android:color="?androidprv:attr/materialColorPrimary" />
+    <solid android:color="@androidprv:color/materialColorPrimary" />
     <corners android:radius="@dimen/volume_dialog_ringer_selected_button_background_radius" />
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/volume_ringer_item_bg.xml b/packages/SystemUI/res/drawable/volume_ringer_item_bg.xml
index a8c9818..4b3edb9 100644
--- a/packages/SystemUI/res/drawable/volume_ringer_item_bg.xml
+++ b/packages/SystemUI/res/drawable/volume_ringer_item_bg.xml
@@ -17,6 +17,6 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:shape="rectangle" >
     <size android:width="@dimen/volume_dialog_ringer_drawer_button_size" android:height="@dimen/volume_dialog_ringer_drawer_button_size"/>
-    <solid android:color="?androidprv:attr/materialColorSurfaceContainerHighest" />
+    <solid android:color="@androidprv:color/materialColorSurfaceContainerHighest" />
     <corners android:radius="@dimen/volume_dialog_background_square_corner_radius" />
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/volume_row_seekbar.xml b/packages/SystemUI/res/drawable/volume_row_seekbar.xml
index d7d75d4..c47d7c0 100644
--- a/packages/SystemUI/res/drawable/volume_row_seekbar.xml
+++ b/packages/SystemUI/res/drawable/volume_row_seekbar.xml
@@ -26,7 +26,7 @@
         <shape>
             <size android:height="@dimen/volume_dialog_track_width" />
             <corners android:radius="@dimen/volume_dialog_panel_width_half" />
-            <solid android:color="?androidprv:attr/materialColorOutlineVariant" />
+            <solid android:color="@androidprv:color/materialColorOutlineVariant" />
         </shape>
     </item>
     <item android:id="@android:id/progress"
diff --git a/packages/SystemUI/res/layout/alert_dialog_title_systemui.xml b/packages/SystemUI/res/layout/alert_dialog_title_systemui.xml
index ca7df86..3e53bf4 100644
--- a/packages/SystemUI/res/layout/alert_dialog_title_systemui.xml
+++ b/packages/SystemUI/res/layout/alert_dialog_title_systemui.xml
@@ -42,7 +42,7 @@
             android:layout_marginBottom="16dp"
             android:scaleType="fitCenter"
             android:src="@null"
-            android:tint="?androidprv:attr/materialColorPrimary"
+            android:tint="@androidprv:color/materialColorPrimary"
             />
 
         <TextView
diff --git a/packages/SystemUI/res/layout/app_clips_screenshot.xml b/packages/SystemUI/res/layout/app_clips_screenshot.xml
index 7b7c96cb..afc58cc 100644
--- a/packages/SystemUI/res/layout/app_clips_screenshot.xml
+++ b/packages/SystemUI/res/layout/app_clips_screenshot.xml
@@ -31,10 +31,10 @@
         android:layout_height="48dp"
         android:layout_marginStart="8dp"
         android:background="@drawable/overlay_button_background"
-        android:backgroundTint="?androidprv:attr/materialColorPrimary"
+        android:backgroundTint="@androidprv:color/materialColorPrimary"
         android:paddingHorizontal="24dp"
         android:text="@string/app_clips_save_add_to_note"
-        android:textColor="?androidprv:attr/materialColorOnPrimary"
+        android:textColor="@androidprv:color/materialColorOnPrimary"
         app:layout_constraintBottom_toTopOf="@id/preview"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
@@ -61,7 +61,7 @@
         android:button="@drawable/checkbox_circle_shape"
         android:checked="true"
         android:text="@string/backlinks_include_link"
-        android:textColor="?androidprv:attr/materialColorOnBackground"
+        android:textColor="@androidprv:color/materialColorOnBackground"
         android:visibility="gone"
         app:layout_constraintBottom_toTopOf="@id/preview"
         app:layout_constraintStart_toEndOf="@id/cancel"
@@ -89,11 +89,11 @@
         android:layout_marginStart="8dp"
         android:drawablePadding="4dp"
         android:drawableStart="@drawable/ic_info_outline"
-        android:drawableTint="?androidprv:attr/materialColorOnBackground"
+        android:drawableTint="@androidprv:color/materialColorOnBackground"
         android:gravity="center"
         android:paddingHorizontal="8dp"
         android:text="@string/backlinks_cross_profile_error"
-        android:textColor="?androidprv:attr/materialColorOnBackground"
+        android:textColor="@androidprv:color/materialColorOnBackground"
         android:visibility="gone"
         app:layout_constraintBottom_toTopOf="@id/preview"
         app:layout_constraintStart_toEndOf="@id/backlinks_data"
diff --git a/packages/SystemUI/res/layout/bundle_notification_info.xml b/packages/SystemUI/res/layout/bundle_notification_info.xml
index 8700832..745066a 100644
--- a/packages/SystemUI/res/layout/bundle_notification_info.xml
+++ b/packages/SystemUI/res/layout/bundle_notification_info.xml
@@ -103,7 +103,7 @@
             android:contentDescription="@string/notification_app_settings"
             android:src="@drawable/ic_info"
             android:layout_toStartOf="@id/info"
-            android:tint="?androidprv:attr/materialColorPrimary"/>
+            android:tint="@androidprv:color/materialColorPrimary"/>
         <ImageButton
             android:id="@+id/info"
             android:layout_width="@dimen/notification_importance_toggle_size"
@@ -112,7 +112,7 @@
             android:contentDescription="@string/notification_more_settings"
             android:background="@drawable/ripple_drawable_20dp"
             android:src="@drawable/ic_settings"
-            android:tint="?androidprv:attr/materialColorPrimary"
+            android:tint="@androidprv:color/materialColorPrimary"
             android:layout_alignParentEnd="true" />
 
     </LinearLayout>
diff --git a/packages/SystemUI/res/layout/chipbar.xml b/packages/SystemUI/res/layout/chipbar.xml
index e1b8ab4..2fecf79 100644
--- a/packages/SystemUI/res/layout/chipbar.xml
+++ b/packages/SystemUI/res/layout/chipbar.xml
@@ -56,10 +56,10 @@
             android:layout_height="wrap_content"
             android:layout_weight="1"
             style="@style/Chipbar.Text"
-            android:textColor="?androidprv:attr/materialColorOnSecondaryFixed"
+            android:textColor="@androidprv:color/materialColorOnSecondaryFixed"
             android:alpha="0.0"
             />
-        <!-- LINT.ThenChange(systemui.temporarydisplay.chipbar.ChipbarInfo.kt) -->
+        <!-- LINT.ThenChange(/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt) -->
 
         <!-- At most one of [loading, failure_icon, undo] will be visible at a time. -->
         <ImageView
@@ -68,7 +68,7 @@
             android:layout_height="@dimen/chipbar_end_icon_size"
             android:layout_marginStart="@dimen/chipbar_end_item_start_margin"
             android:src="@drawable/ic_progress_activity"
-            android:tint="?androidprv:attr/materialColorOnSecondaryFixedVariant"
+            android:tint="@androidprv:color/materialColorOnSecondaryFixedVariant"
             android:alpha="0.0"
             />
 
@@ -88,7 +88,7 @@
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/chipbar_end_item_start_margin"
             style="@style/Chipbar.Text"
-            android:textColor="?androidprv:attr/materialColorOnPrimaryFixed"
+            android:textColor="@androidprv:color/materialColorOnPrimaryFixed"
             android:paddingStart="@dimen/chipbar_outer_padding"
             android:paddingEnd="@dimen/chipbar_outer_padding"
             android:paddingTop="@dimen/chipbar_end_button_vertical_padding"
diff --git a/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml b/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
index 14b3b55..3378dcc 100644
--- a/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
+++ b/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
@@ -17,8 +17,8 @@
         android:paddingHorizontal="16dp"
         android:background="@drawable/overlay_button_background"
         android:text="@string/clipboard_edit_text_done"
-        android:backgroundTint="?androidprv:attr/materialColorPrimary"
-        android:textColor="?androidprv:attr/materialColorOnPrimary"
+        android:backgroundTint="@androidprv:color/materialColorPrimary"
+        android:textColor="@androidprv:color/materialColorOnPrimary"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
 
diff --git a/packages/SystemUI/res/layout/clipboard_overlay.xml b/packages/SystemUI/res/layout/clipboard_overlay.xml
index 572f063..448b3e7 100644
--- a/packages/SystemUI/res/layout/clipboard_overlay.xml
+++ b/packages/SystemUI/res/layout/clipboard_overlay.xml
@@ -222,8 +222,8 @@
             android:layout_height="match_parent"
             android:layout_margin="@dimen/overlay_dismiss_button_margin"
             android:background="@drawable/circular_background"
-            android:backgroundTint="?androidprv:attr/materialColorPrimaryFixedDim"
-            android:tint="?androidprv:attr/materialColorOnPrimaryFixed"
+            android:backgroundTint="@androidprv:color/materialColorPrimaryFixedDim"
+            android:tint="@androidprv:color/materialColorOnPrimaryFixed"
             android:padding="4dp"
             android:src="@drawable/ic_close"/>
     </FrameLayout>
diff --git a/packages/SystemUI/res/layout/connected_display_dialog.xml b/packages/SystemUI/res/layout/connected_display_dialog.xml
index a71782b..b223555 100644
--- a/packages/SystemUI/res/layout/connected_display_dialog.xml
+++ b/packages/SystemUI/res/layout/connected_display_dialog.xml
@@ -30,11 +30,11 @@
         android:layout_width="@dimen/connected_display_dialog_logo_size"
         android:layout_height="@dimen/connected_display_dialog_logo_size"
         android:background="@drawable/circular_background"
-        android:backgroundTint="?androidprv:attr/materialColorSecondary"
+        android:backgroundTint="@androidprv:color/materialColorSecondary"
         android:importantForAccessibility="no"
         android:padding="6dp"
         android:src="@drawable/stat_sys_connected_display"
-        android:tint="?androidprv:attr/materialColorOnSecondary" />
+        android:tint="@androidprv:color/materialColorOnSecondary" />
 
     <TextView
         android:id="@+id/connected_display_dialog_title"
diff --git a/packages/SystemUI/res/layout/contextual_edu_dialog.xml b/packages/SystemUI/res/layout/contextual_edu_dialog.xml
index 7eb6efe..09aa8da 100644
--- a/packages/SystemUI/res/layout/contextual_edu_dialog.xml
+++ b/packages/SystemUI/res/layout/contextual_edu_dialog.xml
@@ -39,6 +39,7 @@
         android:ellipsize="end"
         android:fontFamily="google-sans-medium"
         android:maxWidth="280dp"
-        android:textColor="?androidprv:attr/materialColorOnTertiaryFixed"
-        android:textSize="14sp" />
+        android:textColor="@androidprv:color/materialColorOnTertiaryFixed"
+        android:textSize="14sp"
+        android:textStyle="bold" />
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout/hearing_devices_spinner_dropdown_view.xml b/packages/SystemUI/res/layout/hearing_devices_spinner_dropdown_view.xml
index 70f2cd5..2d799ae 100644
--- a/packages/SystemUI/res/layout/hearing_devices_spinner_dropdown_view.xml
+++ b/packages/SystemUI/res/layout/hearing_devices_spinner_dropdown_view.xml
@@ -28,7 +28,7 @@
         android:layout_height="@dimen/hearing_devices_preset_spinner_icon_size"
         android:layout_gravity="center_vertical"
         android:layout_marginEnd="@dimen/hearing_devices_layout_margin"
-        android:tint="?androidprv:attr/materialColorOnPrimaryContainer"
+        android:tint="@androidprv:color/materialColorOnPrimaryContainer"
         android:src="@drawable/ic_check"
         android:contentDescription="@string/hearing_devices_spinner_item_selected"/>
     <TextView
diff --git a/packages/SystemUI/res/layout/immersive_mode_cling.xml b/packages/SystemUI/res/layout/immersive_mode_cling.xml
index 20b7cd3..f12cf96 100644
--- a/packages/SystemUI/res/layout/immersive_mode_cling.xml
+++ b/packages/SystemUI/res/layout/immersive_mode_cling.xml
@@ -42,7 +42,7 @@
         android:layout_marginTop="20dp"
         android:gravity="center_horizontal"
         android:text="@string/immersive_cling_title"
-        android:textColor="?androidprv:attr/materialColorOnSurface"
+        android:textColor="@androidprv:color/materialColorOnSurface"
         android:textSize="24sp"
         android:fontFamily="google-sans" />
 
@@ -54,7 +54,7 @@
         android:paddingTop="14dp"
         android:gravity="center_horizontal"
         android:text="@string/immersive_cling_description"
-        android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+        android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
         android:textSize="14sp"
         android:fontFamily="google-sans" />
 
@@ -72,7 +72,7 @@
         android:minWidth="48dp"
         android:minHeight="48dp"
         android:text="@string/immersive_cling_positive"
-        android:textColor="?androidprv:attr/materialColorOnPrimary"
+        android:textColor="@androidprv:color/materialColorOnPrimary"
         android:textAllCaps="false"
         android:textSize="14sp"
         android:textFontWeight="500"
diff --git a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
index 2b40df4..5922a7d 100644
--- a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
+++ b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
@@ -149,7 +149,8 @@
                         android:clickable="false"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
-                        android:gravity="start|center_vertical">
+                        android:minHeight="72dp"
+                        android:gravity="center_vertical">
                         <TextView
                             android:id="@+id/mobile_title"
                             android:maxLines="1"
diff --git a/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml b/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml
index 5ab2327..4a40dda4 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml
@@ -40,7 +40,7 @@
             android:layout_height="wrap_content"
             android:paddingEnd="12dp"
             android:paddingBottom="4dp"
-            android:textColor="?androidprv:attr/materialColorOnSurface"
+            android:textColor="@androidprv:color/materialColorOnSurface"
             android:textAppearance="?android:attr/textAppearanceMedium"
             android:textSize="16sp"
             android:maxLines="5"
diff --git a/packages/SystemUI/res/layout/keyboard_shortcuts_category_title.xml b/packages/SystemUI/res/layout/keyboard_shortcuts_category_title.xml
index 6e7fde6..3e69a66 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcuts_category_title.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcuts_category_title.xml
@@ -21,7 +21,7 @@
           android:layout_height="match_parent"
           android:textAppearance="?android:attr/textAppearanceMedium"
           android:textSize="14sp"
-          android:textColor="?androidprv:attr/materialColorPrimary"
+          android:textColor="@androidprv:color/materialColorPrimary"
           android:importantForAccessibility="yes"
           android:paddingTop="20dp"
           android:paddingBottom="10dp"/>
diff --git a/packages/SystemUI/res/layout/keyboard_shortcuts_key_separator_view.xml b/packages/SystemUI/res/layout/keyboard_shortcuts_key_separator_view.xml
index 8772a73..5bba9ba 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcuts_key_separator_view.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcuts_key_separator_view.xml
@@ -22,7 +22,7 @@
     android:layout_marginLeft="0dp"
     android:layout_marginRight="0dp"
     android:text="@string/keyboard_shortcut_join"
-    android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+    android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
     android:singleLine="true"
     android:gravity="center"
     android:textSize="@dimen/ksh_item_text_size" />
diff --git a/packages/SystemUI/res/layout/keyboard_shortcuts_key_view.xml b/packages/SystemUI/res/layout/keyboard_shortcuts_key_view.xml
index 42bbf25..91558fd 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcuts_key_view.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcuts_key_view.xml
@@ -25,7 +25,7 @@
         android:paddingBottom="@dimen/ksh_key_view_padding_vertical"
         android:layout_marginStart="@dimen/ksh_item_margin_start"
         android:background="@drawable/ksh_key_item_background"
-        android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+        android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
         android:singleLine="true"
         android:gravity="center"
         android:textSize="@dimen/ksh_item_text_size" />
diff --git a/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml b/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml
index 45a4af9..18716ef 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml
@@ -52,14 +52,14 @@
             android:drawableStart="@drawable/ic_shortcutlist_search"
             android:drawablePadding="15dp"
             android:singleLine="true"
-            android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+            android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
             android:inputType="text"
             android:textDirection="locale"
             android:textAlignment="viewStart"
             android:hint="@string/keyboard_shortcut_search_list_hint"
             android:textAppearance="@android:style/TextAppearance.Material"
             android:textSize="16sp"
-            android:textColorHint="?androidprv:attr/materialColorOutline" />
+            android:textColorHint="@androidprv:color/materialColorOutline" />
 
         <ImageButton
             android:id="@+id/keyboard_shortcuts_search_cancel"
diff --git a/packages/SystemUI/res/layout/keyguard_settings_popup_menu.xml b/packages/SystemUI/res/layout/keyguard_settings_popup_menu.xml
index 636f479..e47fc62 100644
--- a/packages/SystemUI/res/layout/keyguard_settings_popup_menu.xml
+++ b/packages/SystemUI/res/layout/keyguard_settings_popup_menu.xml
@@ -32,7 +32,7 @@
         android:layout_width="@dimen/keyguard_settings_popup_menu_icon_height"
         android:layout_height="@dimen/keyguard_settings_popup_menu_icon_width"
         android:layout_marginEnd="@dimen/keyguard_settings_popup_menu_icon_end_margin"
-        android:tint="?androidprv:attr/materialColorOnSecondaryFixed"
+        android:tint="@androidprv:color/materialColorOnSecondaryFixed"
         android:importantForAccessibility="no"
         tools:ignore="UseAppTint" />
 
@@ -41,7 +41,7 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textAppearance="?android:attr/textAppearanceMedium"
-        android:textColor="?androidprv:attr/materialColorOnSecondaryFixed"
+        android:textColor="@androidprv:color/materialColorOnSecondaryFixed"
         android:textSize="14sp"
         android:maxLines="1"
         android:ellipsize="end" />
diff --git a/packages/SystemUI/res/layout/long_screenshot.xml b/packages/SystemUI/res/layout/long_screenshot.xml
index 4d207da..87433be 100644
--- a/packages/SystemUI/res/layout/long_screenshot.xml
+++ b/packages/SystemUI/res/layout/long_screenshot.xml
@@ -32,8 +32,8 @@
         android:layout_marginStart="8dp"
         android:layout_marginTop="@dimen/long_screenshot_action_bar_top_margin"
         android:background="@drawable/overlay_button_background"
-        android:backgroundTint="?androidprv:attr/materialColorPrimary"
-        android:textColor="?androidprv:attr/materialColorOnPrimary"
+        android:backgroundTint="@androidprv:color/materialColorPrimary"
+        android:textColor="@androidprv:color/materialColorOnPrimary"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintBottom_toTopOf="@id/preview" />
@@ -47,8 +47,8 @@
         android:layout_marginStart="6dp"
         android:layout_marginTop="@dimen/long_screenshot_action_bar_top_margin"
         android:background="@drawable/overlay_button_outline"
-        android:backgroundTint="?androidprv:attr/materialColorPrimary"
-        android:textColor="?androidprv:attr/materialColorOnSurface"
+        android:backgroundTint="@androidprv:color/materialColorPrimary"
+        android:textColor="@androidprv:color/materialColorOnSurface"
         app:layout_constraintStart_toEndOf="@id/save"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintBottom_toTopOf="@id/preview"
@@ -57,7 +57,7 @@
     <ImageButton
         android:id="@+id/share"
         style="@android:style/Widget.Material.Button.Borderless"
-        android:tint="?androidprv:attr/materialColorOnSurface"
+        android:tint="@androidprv:color/materialColorOnSurface"
         android:layout_width="48dp"
         android:layout_height="48dp"
         android:layout_marginEnd="8dp"
@@ -114,10 +114,10 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintBottom_toBottomOf="parent"
         app:handleThickness="@dimen/screenshot_crop_handle_thickness"
-        app:handleColor="?androidprv:attr/materialColorSecondary"
-        app:scrimColor="?androidprv:attr/materialColorSurfaceContainer"
+        app:handleColor="@androidprv:color/materialColorSecondary"
+        app:scrimColor="@androidprv:color/materialColorSurfaceContainer"
         app:scrimAlpha="128"
-        app:containerBackgroundColor="?androidprv:attr/materialColorSurfaceContainer"
+        app:containerBackgroundColor="@androidprv:color/materialColorSurfaceContainer"
         tools:background="?android:colorBackground"
         tools:minHeight="100dp"
         tools:minWidth="100dp" />
@@ -131,11 +131,11 @@
         app:layout_constraintTop_toTopOf="@id/preview"
         app:layout_constraintLeft_toLeftOf="parent"
         app:handleThickness="@dimen/screenshot_crop_handle_thickness"
-        app:handleColor="?androidprv:attr/materialColorSecondary"
-        app:scrimColor="?androidprv:attr/materialColorSurfaceContainer"
+        app:handleColor="@androidprv:color/materialColorSecondary"
+        app:scrimColor="@androidprv:color/materialColorSurfaceContainer"
         app:scrimAlpha="128"
         app:borderThickness="4dp"
-        app:borderColor="?androidprv:attr/materialColorSurfaceBright" />
+        app:borderColor="@androidprv:color/materialColorSurfaceBright" />
 
     <ImageButton
         android:id="@+id/edit"
@@ -147,7 +147,7 @@
         android:background="@drawable/screenshot_edit_background"
         android:src="@drawable/ic_screenshot_edit"
         android:contentDescription="@string/screenshot_edit_label"
-        android:tint="?androidprv:attr/materialColorOnSecondaryFixed"
+        android:tint="@androidprv:color/materialColorOnSecondaryFixed"
         android:padding="16dp"
         android:scaleType="fitCenter"
         app:layout_constraintBottom_toBottomOf="parent"
diff --git a/packages/SystemUI/res/layout/notif_half_shelf.xml b/packages/SystemUI/res/layout/notif_half_shelf.xml
index d8d2985..9a66ca9 100644
--- a/packages/SystemUI/res/layout/notif_half_shelf.xml
+++ b/packages/SystemUI/res/layout/notif_half_shelf.xml
@@ -66,7 +66,7 @@
                     android:gravity="center_vertical|start"
                     android:ellipsize="end"
                     android:maxLines="2"
-                    android:textColor="?androidprv:attr/materialColorOnSurface"
+                    android:textColor="@androidprv:color/materialColorOnSurface"
                     android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
                     android:textSize="16sp"
                 />
diff --git a/packages/SystemUI/res/layout/notif_half_shelf_row.xml b/packages/SystemUI/res/layout/notif_half_shelf_row.xml
index 9ef342c..b2eaa6c 100644
--- a/packages/SystemUI/res/layout/notif_half_shelf_row.xml
+++ b/packages/SystemUI/res/layout/notif_half_shelf_row.xml
@@ -60,7 +60,7 @@
                 android:ellipsize="end"
                 android:maxLines="1"
                 android:fontFamily="@*android:string/config_headlineFontFamily"
-                android:textColor="?androidprv:attr/materialColorOnSurface"
+                android:textColor="@androidprv:color/materialColorOnSurface"
                 android:textSize="16sp"
             />
 
@@ -75,7 +75,7 @@
                 android:maxLines="1"
                 android:layout_below="@id/channel_name"
                 android:fontFamily="@*android:string/config_bodyFontFamily"
-                android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+                android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
                 android:textSize="14sp"
             />
         </RelativeLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_footer_redesign.xml b/packages/SystemUI/res/layout/notification_2025_footer.xml
similarity index 97%
rename from packages/SystemUI/res/layout/status_bar_notification_footer_redesign.xml
rename to packages/SystemUI/res/layout/notification_2025_footer.xml
index 71c77a5..9b3d67f 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_footer_redesign.xml
+++ b/packages/SystemUI/res/layout/notification_2025_footer.xml
@@ -64,6 +64,8 @@
                 android:contentDescription="@string/accessibility_clear_all"
                 android:focusable="true"
                 android:text="@string/clear_all_notifications_text"
+                android:ellipsize="end"
+                android:maxLines="1"
                 app:layout_constraintEnd_toStartOf="@id/settings_button"
                 app:layout_constraintStart_toEndOf="@id/history_button" />
 
diff --git a/packages/SystemUI/res/layout/notification_children_divider.xml b/packages/SystemUI/res/layout/notification_children_divider.xml
index 13e24a9..c1d94f9 100644
--- a/packages/SystemUI/res/layout/notification_children_divider.xml
+++ b/packages/SystemUI/res/layout/notification_children_divider.xml
@@ -21,4 +21,4 @@
     android:id="@+id/notification_more_divider"
     android:layout_width="match_parent"
     android:layout_height="@dimen/notification_divider_height"
-    android:background="?androidprv:attr/materialColorOnSurfaceVariant" />
+    android:background="@androidprv:color/materialColorOnSurfaceVariant" />
diff --git a/packages/SystemUI/res/layout/notification_conversation_info.xml b/packages/SystemUI/res/layout/notification_conversation_info.xml
index 3a752c8..cb9d8115d 100644
--- a/packages/SystemUI/res/layout/notification_conversation_info.xml
+++ b/packages/SystemUI/res/layout/notification_conversation_info.xml
@@ -174,7 +174,7 @@
             android:contentDescription="@string/notification_more_settings"
             android:background="@drawable/ripple_drawable_20dp"
             android:src="@drawable/ic_settings"
-            android:tint="?androidprv:attr/materialColorPrimary"
+            android:tint="@androidprv:color/materialColorPrimary"
             android:layout_alignParentEnd="true" />
 
     </LinearLayout>
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index 19a3f2f..edca7e3 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -103,7 +103,7 @@
             android:contentDescription="@string/notification_app_settings"
             android:src="@drawable/ic_info"
             android:layout_toStartOf="@id/info"
-            android:tint="?androidprv:attr/materialColorPrimary"/>
+            android:tint="@androidprv:color/materialColorPrimary"/>
         <ImageButton
             android:id="@+id/info"
             android:layout_width="@dimen/notification_importance_toggle_size"
@@ -112,7 +112,7 @@
             android:contentDescription="@string/notification_more_settings"
             android:background="@drawable/ripple_drawable_20dp"
             android:src="@drawable/ic_settings"
-            android:tint="?androidprv:attr/materialColorPrimary"
+            android:tint="@androidprv:color/materialColorPrimary"
             android:layout_alignParentEnd="true" />
 
     </LinearLayout>
diff --git a/packages/SystemUI/res/layout/notification_snooze.xml b/packages/SystemUI/res/layout/notification_snooze.xml
index ce09385..f114f4c 100644
--- a/packages/SystemUI/res/layout/notification_snooze.xml
+++ b/packages/SystemUI/res/layout/notification_snooze.xml
@@ -23,7 +23,7 @@
     android:orientation="vertical"
     android:paddingTop="2dp"
     android:paddingBottom="2dp"
-    android:background="?androidprv:attr/materialColorSurfaceContainerHigh"
+    android:background="@androidprv:color/materialColorSurfaceContainerHigh"
     android:theme="@style/Theme.SystemUI">
 
     <RelativeLayout
@@ -38,7 +38,7 @@
             android:layout_alignParentStart="true"
             android:layout_centerVertical="true"
             android:paddingStart="@*android:dimen/notification_content_margin_end"
-            android:textColor="?androidprv:attr/materialColorOnSurface"
+            android:textColor="@androidprv:color/materialColorOnSurface"
             android:paddingEnd="4dp"/>
 
         <ImageView
diff --git a/packages/SystemUI/res/layout/notification_snooze_option.xml b/packages/SystemUI/res/layout/notification_snooze_option.xml
index fa6f965..364b44c 100644
--- a/packages/SystemUI/res/layout/notification_snooze_option.xml
+++ b/packages/SystemUI/res/layout/notification_snooze_option.xml
@@ -23,4 +23,4 @@
         android:layout_marginEnd="@*android:dimen/notification_content_margin_end"
         android:gravity="center_vertical"
         android:textSize="14sp"
-        android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"/>
\ No newline at end of file
+        android:textColor="@androidprv:color/materialColorOnSurfaceVariant"/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/privacy_dialog_item_v2.xml b/packages/SystemUI/res/layout/privacy_dialog_item_v2.xml
index b84f3a9..3ca4b94 100644
--- a/packages/SystemUI/res/layout/privacy_dialog_item_v2.xml
+++ b/packages/SystemUI/res/layout/privacy_dialog_item_v2.xml
@@ -25,7 +25,7 @@
     android:foreground="?android:attr/selectableItemBackground"
     app:cardCornerRadius="28dp"
     app:cardElevation="0dp"
-    app:cardBackgroundColor="?androidprv:attr/materialColorSurfaceBright">
+    app:cardBackgroundColor="@androidprv:color/materialColorSurfaceBright">
     <LinearLayout
         android:orientation="vertical"
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/privacy_dialog_v2.xml b/packages/SystemUI/res/layout/privacy_dialog_v2.xml
index 76098a1..0392322 100644
--- a/packages/SystemUI/res/layout/privacy_dialog_v2.xml
+++ b/packages/SystemUI/res/layout/privacy_dialog_v2.xml
@@ -45,7 +45,7 @@
                 android:layout_height="wrap_content"
                 android:text="@string/privacy_dialog_summary"
                 android:textAppearance="?android:attr/textAppearanceSmall"
-                android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+                android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
                 android:gravity="center"
                 android:layout_marginBottom="20dp"/>
         </LinearLayout>
diff --git a/packages/SystemUI/res/layout/record_issue_dialog.xml b/packages/SystemUI/res/layout/record_issue_dialog.xml
index b2a8c4c..76a7d34 100644
--- a/packages/SystemUI/res/layout/record_issue_dialog.xml
+++ b/packages/SystemUI/res/layout/record_issue_dialog.xml
@@ -55,7 +55,7 @@
             android:layout_height="@dimen/screenrecord_option_icon_size"
             android:layout_weight="0"
             android:src="@drawable/ic_screenrecord"
-            app:tint="?androidprv:attr/materialColorOnSurface"
+            app:tint="@androidprv:color/materialColorOnSurface"
             android:importantForAccessibility="no"
             android:layout_gravity="center"
             android:layout_marginEnd="@dimen/screenrecord_option_padding" />
@@ -95,7 +95,7 @@
             android:layout_height="@dimen/screenrecord_option_icon_size"
             android:layout_weight="0"
             android:src="@drawable/ic_bugreport"
-            app:tint="?androidprv:attr/materialColorOnSurface"
+            app:tint="@androidprv:color/materialColorOnSurface"
             android:importantForAccessibility="no"
             android:layout_gravity="center"
             android:layout_marginEnd="@dimen/screenrecord_option_padding" />
diff --git a/packages/SystemUI/res/layout/screen_share_dialog.xml b/packages/SystemUI/res/layout/screen_share_dialog.xml
index 0533c7e..78d1ab2 100644
--- a/packages/SystemUI/res/layout/screen_share_dialog.xml
+++ b/packages/SystemUI/res/layout/screen_share_dialog.xml
@@ -36,7 +36,7 @@
             android:layout_width="@dimen/screenrecord_logo_size"
             android:layout_height="@dimen/screenrecord_logo_size"
             android:src="@drawable/ic_media_projection_permission"
-            android:tint="?androidprv:attr/materialColorPrimary"
+            android:tint="@androidprv:color/materialColorPrimary"
             android:importantForAccessibility="no"/>
         <TextView
             android:id="@+id/screen_share_dialog_title"
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 8c31713..1ef010b 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
@@ -39,6 +39,6 @@
         android:ellipsize="marquee"
         android:singleLine="true"
         android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="?androidprv:attr/materialColorError" />
+        android:textColor="@androidprv:color/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 fff1de7..f03c032 100644
--- a/packages/SystemUI/res/layout/screenshot_shelf.xml
+++ b/packages/SystemUI/res/layout/screenshot_shelf.xml
@@ -127,8 +127,8 @@
                 android:layout_height="match_parent"
                 android:layout_margin="@dimen/overlay_dismiss_button_margin"
                 android:background="@drawable/circular_background"
-                android:backgroundTint="?androidprv:attr/materialColorPrimary"
-                android:tint="?androidprv:attr/materialColorOnPrimary"
+                android:backgroundTint="@androidprv:color/materialColorPrimary"
+                android:tint="@androidprv:color/materialColorOnPrimary"
                 android:padding="4dp"
                 android:src="@drawable/ic_close"/>
         </FrameLayout>
diff --git a/packages/SystemUI/res/layout/screenshot_work_profile_first_run.xml b/packages/SystemUI/res/layout/screenshot_work_profile_first_run.xml
index 39ec09b..9803871 100644
--- a/packages/SystemUI/res/layout/screenshot_work_profile_first_run.xml
+++ b/packages/SystemUI/res/layout/screenshot_work_profile_first_run.xml
@@ -38,8 +38,8 @@
             android:layout_height="24dp"
             android:layout_gravity="center"
             android:background="@drawable/circular_background"
-            android:backgroundTint="?androidprv:attr/materialColorSurfaceContainerHigh"
-            android:tint="?androidprv:attr/materialColorOnSurface"
+            android:backgroundTint="@androidprv:color/materialColorSurfaceContainerHigh"
+            android:tint="@androidprv:color/materialColorOnSurface"
             android:padding="2dp"
             android:src="@drawable/ic_close"/>
     </FrameLayout>
diff --git a/packages/SystemUI/res/layout/shelf_action_chip.xml b/packages/SystemUI/res/layout/shelf_action_chip.xml
index 1c65e36..430e9f7 100644
--- a/packages/SystemUI/res/layout/shelf_action_chip.xml
+++ b/packages/SystemUI/res/layout/shelf_action_chip.xml
@@ -27,7 +27,7 @@
     >
     <ImageView
         android:id="@+id/overlay_action_chip_icon"
-        android:tint="?androidprv:attr/materialColorOnSecondary"
+        android:tint="@androidprv:color/materialColorOnSecondary"
         android:tintMode="src_in"
         android:layout_width="@dimen/overlay_action_chip_icon_size"
         android:layout_height="@dimen/overlay_action_chip_icon_size"/>
@@ -37,5 +37,5 @@
         android:layout_height="wrap_content"
         android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
         android:textSize="@dimen/overlay_action_chip_text_size"
-        android:textColor="?androidprv:attr/materialColorOnSecondary"/>
+        android:textColor="@androidprv:color/materialColorOnSecondary"/>
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index b8544a6..a3bad8f 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -58,7 +58,7 @@
         android:contentDescription="@string/accessibility_volume_settings"
         android:soundEffectsEnabled="false"
         android:src="@drawable/horizontal_ellipsis"
-        android:tint="?androidprv:attr/materialColorPrimary"
+        android:tint="@androidprv:color/materialColorPrimary"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="@id/volume_dialog_main_slider_container"
         app:layout_constraintStart_toStartOf="@id/volume_dialog_main_slider_container"
@@ -79,4 +79,4 @@
         app:layout_constraintEnd_toStartOf="@id/volume_dialog_background"
         app:layout_constraintTop_toTopOf="@id/volume_dialog_main_slider_container" />
 
-</androidx.constraintlayout.motion.widget.MotionLayout>
\ No newline at end of file
+</androidx.constraintlayout.motion.widget.MotionLayout>
diff --git a/packages/SystemUI/res/layout/volume_dialog_slider.xml b/packages/SystemUI/res/layout/volume_dialog_slider.xml
index c1852b1..9ac456c 100644
--- a/packages/SystemUI/res/layout/volume_dialog_slider.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_slider.xml
@@ -14,15 +14,21 @@
      limitations under the License.
 -->
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="@dimen/volume_dialog_slider_width"
-    android:layout_height="@dimen/volume_dialog_slider_height">
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
 
     <com.google.android.material.slider.Slider
-        style="@style/SystemUI.Material3.Slider.Volume"
         android:id="@+id/volume_dialog_slider"
-        android:layout_width="@dimen/volume_dialog_slider_height"
-        android:layout_height="match_parent"
+        style="@style/SystemUI.Material3.Slider.Volume"
+        android:layout_width="@dimen/volume_dialog_slider_width"
+        android:layout_height="@dimen/volume_dialog_slider_height"
         android:layout_gravity="center"
-        android:rotation="270"
-        android:theme="@style/Theme.Material3.Light" />
-</FrameLayout>
+        android:theme="@style/Theme.Material3.Light"
+        android:orientation="vertical"
+        app:thumbHeight="52dp"
+        app:trackCornerSize="12dp"
+        app:trackHeight="40dp"
+        app:trackStopIndicatorSize="6dp"
+        app:trackInsideCornerSize="2dp" />
+</FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/volume_ringer_button.xml b/packages/SystemUI/res/layout/volume_ringer_button.xml
index 38bb783..e65d0b9 100644
--- a/packages/SystemUI/res/layout/volume_ringer_button.xml
+++ b/packages/SystemUI/res/layout/volume_ringer_button.xml
@@ -26,7 +26,7 @@
         android:layout_marginBottom="@dimen/volume_dialog_components_spacing"
         android:contentDescription="@string/volume_ringer_mode"
         android:gravity="center"
-        android:tint="?androidprv:attr/materialColorOnSurface"
+        android:tint="@androidprv:color/materialColorOnSurface"
         android:src="@drawable/volume_ringer_item_bg"
         android:background="@drawable/volume_ringer_item_bg"/>
 
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index b91bfd6..cef0316 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -38,7 +38,7 @@
     <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Laat <xliff:g id="APPLICATION">%1$s</xliff:g> toe om by <xliff:g id="USB_DEVICE">%2$s</xliff:g> in te gaan?\nOpneemtoestemming is nie aan hierdie app verleen nie, maar dit kan oudio deur hierdie USB-toestel vasvang."</string>
     <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Gee <xliff:g id="APPLICATION">%1$s</xliff:g> toegang tot <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
     <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Maak <xliff:g id="APPLICATION">%1$s</xliff:g> oop om <xliff:g id="USB_DEVICE">%2$s</xliff:g> te hanteer?"</string>
-    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Opneemtoestemming is nie aan hierdie program verleen nie, maar dit kan oudio deur hierdie USB-toestel opneem. As jy <xliff:g id="APPLICATION">%1$s</xliff:g> met hierdie toestel gebruik, kan dit verhinder dat jy oproepe, kennisgewings en wekkers hoor."</string>
+    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Opneemtoestemming is nie aan hierdie app verleen nie, maar dit kan oudio deur hierdie USB-toestel opneem. As jy <xliff:g id="APPLICATION">%1$s</xliff:g> met hierdie toestel gebruik, kan dit verhinder dat jy oproepe, kennisgewings en wekkers hoor."</string>
     <string name="usb_audio_device_prompt" msgid="7944987408206252949">"As jy <xliff:g id="APPLICATION">%1$s</xliff:g> met hierdie toestel gebruik, kan dit verhinder dat jy oproepe, kennisgewings en wekkers hoor."</string>
     <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Gee <xliff:g id="APPLICATION">%1$s</xliff:g> toegang tot <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
     <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Hanteer <xliff:g id="USB_DEVICE">%2$s</xliff:g> met <xliff:g id="APPLICATION">%1$s</xliff:g>?"</string>
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Kennisgewings"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Gesprekke"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Vee alle stil kennisgewings uit"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Kennisgewings onderbreek deur Moenie Steur Nie"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Geen kennisgewings nie}=1{Kennisgewings is deur {mode} onderbreek}=2{Kennisgewings is deur {mode} en een ander modus onderbreek}other{Kennisgewings is deur {mode} en # ander modusse onderbreek}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Begin nou"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Kopnasporing"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Tik om luiermodus te verander"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"luiermodus"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"demp"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ontdemp"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibreer"</string>
@@ -1203,8 +1207,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ontkoppel)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan nie wissel nie. Tik om weer te probeer."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Koppel ’n toestel"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Maak die program oop om hierdie sessie uit te saai."</string>
-    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Onbekende program"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Maak die app oop om hierdie sessie uit te saai."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Onbekende app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Hou op uitsaai"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Beskikbare toestelle vir oudio-uitsette."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Druk die handelingsleutel op jou sleutelbord"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Welgedaan!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Jy het die Bekyk Onlangse Apps-gebaar voltooi"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Sleutelbordlig"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Vlak %1$d van %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Huiskontroles"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index cf73b71..5f77743 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ምግብር በመጠቀም መተግበሪያ ለመክፈት እርስዎ መሆንዎን ማረጋገጥ አለብዎት። እንዲሁም የእርስዎ ጡባዊ በተቆለፈበት ጊዜ እንኳን ማንኛውም ሰው እነሱን ማየት እንደሚችል ከግምት ውስጥ ያስገቡ። አንዳንድ ምግብሮች ለማያ ገፅ ቁልፍዎ የታሰቡ ላይሆኑ ይችላሉ እና እዚህ ለማከል አስተማማኝ ላይሆኑ ይችላሉ።"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ገባኝ"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"ምግብሮች"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"የ«ምግብሮች» አቋራጭን ለማከል በቅንብሮች ውስጥ «ምግብሮችን በማያ ገፅ ቁልፍ ላይ አሳይ» የሚለው መንቃቱን ያረጋግጡ።"</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"ቅንብሮች"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ማሳወቂያዎች በአትረብሽ ባሉበት ቆመዋል"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{ምንም ማሳወቂያዎች የሉም}=1{ማሳወቂያዎች በ{mode} ባሉበት ቆመዋል}=2{ማሳወቂያዎች በ{mode} እና አንድ ሌላ ሁነታ ባሉበት ቆመዋል}one{ማሳወቂያዎች በ{mode} እና # ሌላ ሁነታ ባሉበት ቆመዋል}other{ማሳወቂያዎች በ{mode} እና # ሌላ ሁነታዎች ባሉበት ቆመዋል}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"አሁን ጀምር"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"የጭንቅላት ክትትል"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"የደዋይ ሁነታን ለመቀየር መታ ያድርጉ"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"ደዋይ ሁነታ"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ድምጸ-ከል አድርግ"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ድምጸ-ከልን አንሳ"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ንዘር"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"የቁልፍ ሰሌዳ አቋራጮች"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"የቁልፍ ሰሌዳ አቋራጮችን ያብጁ"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"አቋራጭ ይወገድ?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ወደ ነባሪ ዳግም ይጀመር?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"አቋራጭ ለመመደብ ቁልፍ ይጫኑ"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"ይህ ብጁ አቋራጭዎን በቋሚነት ይሰርዛል።"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"ይህ ሁሉንም ብጁ አቋራጮችዎን በቋሚነት ይሰርዛል።"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"የፍለጋ አቋራጮች"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ምንም የፍለጋ ውጤቶች የሉም"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"መሰብሰቢያ አዶ"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"የቁልፍ ሰሌዳ ቅንብሮች"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"አቋራጭ አቀናብር"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"አስወግድ"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"አዎ፣ ዳግም አስጀምር"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ይቅር"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ቁልፍ ይጫኑ"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"የቁልፍ ጥምረት አስቀድሞ በሥራ ላይ ነው። ሌላ ቁልፍ ይሞክሩ።"</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"በቁልፍ ሰሌዳዎ ላይ ያለውን የተግባር ቁልፍ ይጫኑ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ጥሩ ሠርተዋል!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"የሁሉንም መተግበሪያዎች አሳይ ምልክትን አጠናቅቀዋል"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"የቁልፍ ሰሌዳ የጀርባ ብርሃን"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"ደረጃ %1$d ከ %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"የቤት ውስጥ ቁጥጥሮች"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 4ff6131..dd6e850 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"لفتح تطبيق باستخدام تطبيق مصغَّر، عليك إثبات هويتك. يُرجى ملاحظة أنّ أي شخص يمكنه الاطّلاع محتوى التطبيقات المصغَّرة، حتى وإن كان جهازك اللوحي مُقفلاً. بعض التطبيقات المصغّرة قد لا تكون مُصمَّمة لإضافتها إلى شاشة القفل، وقد يكون هذا الإجراء غير آمن."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"حسنًا"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"التطبيقات المصغَّرة"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"لإضافة اختصار \"التطبيقات المصغّرة\"، يجب تفعيل خيار \"عرض التطبيقات المصغّرة على شاشة القفل\" من خلال الإعدادات."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"الإعدادات"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"تم إيقاف الإشعارات مؤقتًا وفقًا لإعداد \"عدم الإزعاج\""</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{ما مِن إشعارات}=1{تم إيقاف الإشعارات مؤقتًا بواسطة \"{mode}\"}=2{تم إيقاف الإشعارات مؤقتًا بواسطة \"{mode}\" ووضع واحد آخر}few{تم إيقاف الإشعارات مؤقتًا بواسطة \"{mode}\" و# أوضاع أخرى}many{تم إيقاف الإشعارات مؤقتًا بواسطة \"{mode}\" و# وضعًا آخر}other{تم إيقاف الإشعارات مؤقتًا بواسطة \"{mode}\" و# وضع آخر}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"البدء الآن"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"تتبُّع حركة الرأس"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"انقر لتغيير وضع الرنين."</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"وضع الرنين"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"كتم الصوت"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"إعادة الصوت"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"اهتزاز"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"اختصارات لوحة المفاتيح"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"تخصيص اختصارات لوحة المفاتيح"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"هل تريد إزالة هذا الاختصار؟"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"يُرجى تأكيد إعادة الضبط على الإعدادات التلقائية"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"اضغط على مفتاح لتخصيص الاختصار"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"سيؤدي هذا الإجراء إلى حذف الاختصار المخصّص نهائيًا."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"سيؤدي هذا الإجراء إلى حذف جميع الاختصارات المخصّصة نهائيًا."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"البحث في الاختصارات"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ما مِن نتائج بحث"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"رمز التصغير"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"إعدادات لوحة المفاتيح"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ضبط الاختصار"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"إزالة"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"نعم، أريد إعادة الضبط"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"إلغاء"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"اضغط على مفتاح"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"يتم حاليًا استخدام مجموعة المفاتيح هذه. يُرجى تجربة مفتاح آخر."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"اضغط على مفتاح الإجراء في لوحة المفاتيح"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"أحسنت!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"لقد أكملْت التدريب على إيماءة عرض جميع التطبيقات"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"الإضاءة الخلفية للوحة المفاتيح"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"‏مستوى الإضاءة: %1$d من %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"إدارة المنزل آليًّا"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index f91a3b0..86e13055 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"এটা ৱিজেট ব্যৱহাৰ কৰি কোনো এপ্ খুলিবলৈ, এয়া আপুনিয়েই বুলি সত্যাপন পৰীক্ষা কৰিব লাগিব। লগতে, মনত ৰাখিব যে যিকোনো লোকেই সেইবোৰ চাব পাৰে, আনকি আপোনাৰ টেবলেটটো লক হৈ থাকিলেও। কিছুমান ৱিজেট হয়তো আপোনাৰ লক স্ক্ৰীনৰ বাবে কৰা হোৱা নাই আৰু ইয়াত যোগ কৰাটো অসুৰক্ষিত হ’ব পাৰে।"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"বুজি পালোঁ"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"ৱিজেট"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"ৱিজেট\"ৰ শ্বৰ্টকাট যোগ দিবলৈ, ছেটিঙত \"লক স্ক্ৰীনত ৱিজেট দেখুৱাওক\" সক্ষম কৰি থোৱাটো নিশ্চিত কৰক।"</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"ছেটিং"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"অসুবিধা নিদিব-ই জাননী পজ কৰিছে"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{কোনো জাননী নাই}=1{{mode}এ জাননী পজ কৰিছে}=2{{mode} আৰু আন এটা ম’ডে জাননী পজ কৰিছে}one{{mode} আৰু আন # টা ম’ডে জাননী পজ কৰিছে}other{{mode} আৰু আন # টা ম’ডে জাননী পজ কৰিছে}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"এতিয়াই আৰম্ভ কৰক"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"হে’ড ট্ৰেকিং"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"ৰিংগাৰ ম’ড সলনি কৰিবলৈ টিপক"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"ৰিংগাৰ ম’ড"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"মিউট কৰক"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"আনমিউট কৰক"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"কম্পন কৰক"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"কীব’ৰ্ডৰ শ্বৰ্টকাট"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"কীব’ৰ্ডৰ শ্বৰ্টকাট কাষ্টমাইজ কৰক"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"শ্বৰ্টকাট আঁতৰাবনে?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ডিফ\'ল্ট হিচাপে পুনৰ ৰিছেট কৰিবনে?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"শ্বৰ্টকাটৰ ভূমিকা অৰ্পণ কৰিবলৈ কী টিপক"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"এইটোৱে আপোনাৰ কাষ্টম শ্বৰ্টকাট মচিব।"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"এইটোৱে আপোনাৰ আটাইবোৰ কাষ্টম শ্বৰ্টকাট স্থায়ীভাৱে মচিব।"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"সন্ধানৰ শ্বৰ্টকাট"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"সন্ধানৰ কোনো ফলাফল নাই"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"সংকোচন কৰাৰ চিহ্ন"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"কীব’ৰ্ডৰ ছেটিং"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"শ্বৰ্টকাট ছেট কৰক"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"আঁতৰাওক"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"হয়, ৰিছেট কৰক"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"বাতিল কৰক"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"কী টিপক"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"কীৰ মিশ্ৰণ ইতিমধ্যে ব্যৱহাৰ হৈ আছে। অন্য এটা কী ব্যৱহাৰ কৰি চাওক।"</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"আপোনাৰ কীব’ৰ্ডৰ কাৰ্য কীটোত টিপক"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"বঢ়িয়া!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"আপুনি আটাইবোৰ এপ্ চোৱাৰ নিৰ্দেশনাটো সম্পূৰ্ণ কৰিছে"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"কীব’ৰ্ডৰ বেকলাইট"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dৰ %1$d স্তৰ"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ঘৰৰ সা-সৰঞ্জামৰ নিয়ন্ত্ৰণ"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 84299dc..3082284 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Bildirişlər"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Söhbətlər"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Səssiz bildirişlərin hamısını silin"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bildirişlər \"Narahat Etməyin\" rejimi tərəfindən dayandırıldı"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Bildiriş yoxdur}=1{Bildirişlər {mode} tərəfindən dayandırıldı}=2{Bildirişlər {mode} və digər rejim tərəfindən dayandırıldı}other{Bildirişlər {mode} və # digər rejim tərəfindən dayandırıldı}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"İndi başlayın"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Baş izləməsi"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Zəng rejimini dəyişmək üçün toxunun"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"zəng səsi rejimi"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"susdurun"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"səssiz rejimdən çıxarın"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrasiya"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Klaviaturada fəaliyyət açarına basın"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Əla!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"\"Bütün tətbiqlərə baxın\" jestini tamamladınız"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatura işığı"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Səviyyə %1$d/%2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Ev nizamlayıcıları"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index bc385a1..09aef06 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Da biste otvorili aplikaciju koja koristi vidžet, treba da potvrdite da ste to vi. Imajte u vidu da svako može da ga vidi, čak i kada je tablet zaključan. Neki vidžeti možda nisu namenjeni za zaključani ekran i možda nije bezbedno da ih tamo dodate."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Važi"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Vidžeti"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Da biste dodali prečicu Vidžeti, uverite se da je u podešavanjima omogućeno Prikazuj vidžete na zaključanom ekranu."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Podešavanja"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zameni korisnika"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji će biti izbrisani."</string>
@@ -593,6 +591,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Obaveštenja"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzacije"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Obrišite sva nečujna obaveštenja"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Obaveštenja su pauzirana režimom Ne uznemiravaj"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Nema obaveštenja}=1{Obaveštenja je pauzirao {mode}}=2{Obaveštenja su pauzirali {mode} i još jedan režim}one{Obaveštenja su pauzirali {mode} i još # režim}few{Obaveštenja su pauzirali {mode} i još # režima}other{Obaveštenja su pauzirali {mode} i još # režima}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Započni"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Praćenje glave"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da biste promenili režim zvona"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"režim zvona"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključite zvuk"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključite zvuk"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibracija"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Tasterske prečice"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodite tasterske prečice"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Želite da uklonite prečicu?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Želite da resetujete na podrazumevano?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pritisnite taster da biste dodelili prečicu"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Ovim ćete trajno izbrisati prilagođenu prečicu."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Time ćete trajno izbrisati sve prilagođene prečice."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pretražite prečice"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretrage"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za skupljanje"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Podešavanja tastature"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Podesi prečicu"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Ukloni"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Da, resetuj"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Otkaži"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite taster"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinacija tastera se već koristi. Probajte sa drugim tasterom."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pritisnite taster radnji na tastaturi"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Odlično!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Dovršili ste pokret za prikazivanje svih aplikacija."</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvetljenje tastature"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. nivo od %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrole za dom"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index a5f4da9..51cc35a 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Каб адкрыць праграму з дапамогай віджэта, вам неабходна будзе пацвердзіць сваю асобу. Таксама памятайце, што такія віджэты могуць пабачыць іншыя людзі, нават калі экран планшэта заблакіраваны. Некаторыя віджэты могуць не падыходзіць для выкарыстання на экране блакіроўкі, і дадаваць іх сюды можа быць небяспечна."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Зразумела"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Віджэты"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Каб дадаць спалучэнне клавіш \"Віджэты\", у наладах павінна быць уключана функцыя \"Паказваць віджэты на экране блакіроўкі\"."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Налады"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Паказ апавяшчэнняў прыпынены ў рэжыме \"Не турбаваць\""</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Апавяшчэнняў няма}=1{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\"}=2{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\" і яшчэ адным рэжымам}one{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\" і яшчэ # рэжымам}few{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\" і яшчэ # рэжымамі}many{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\" і яшчэ # рэжымамі}other{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\" і яшчэ # рэжыму}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Пачаць зараз"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Адсочваць рух галавы"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Націсніце, каб змяніць рэжым званка"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"рэжым званка"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"выключыць гук"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"уключыць гук"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вібрыраваць"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Спалучэнні клавіш"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Наладзіць спалучэнні клавіш"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Выдаліць спалучэнне клавіш?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Скінуць налады да стандартных?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Націсніце клавішу, каб прызначыць спалучэнне клавіш"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Гэта дзеянне назаўсёды выдаліць прызначанае вамі спалучэнне клавіш."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Усе карыстальніцкія спалучэнні клавіш будуць назаўсёды выдалены."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Пошук спалучэнняў клавіш"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Няма вынікаў пошуку"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок \"Згарнуць\""</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Налады клавіятуры"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Наладзіць спалучэнне клавіш"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Выдаліць"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Так, скінуць"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Скасаваць"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Націсніце клавішу"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Гэта спалучэнне клавіш ужо выкарыстоўваецца. Паспрабуйце іншую клавішу."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Націсніце клавішу дзеяння на клавіятуры"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Выдатна!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Вы навучыліся рабіць жэст для прагляду ўсіх праграм"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Падсветка клавіятуры"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Узровень %1$d з %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Кіраванне домам"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index e36cf30..12e25cc 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Известията са поставени на пауза от режима „Не безпокойте“"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Няма известия}=1{Известията са поставени на пауза от {mode}}=2{Известията са поставени на пауза от {mode} и един друг режим}other{Известията са поставени на пауза от {mode} и # други режима}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Стартиране сега"</string>
@@ -707,6 +709,7 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Прослед. на движенията на главата"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Докоснете, за да промените режима на звънене"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"режим на звънене"</string>
+    <string name="volume_ringer_drawer_closed_content_description" msgid="4737792429808781745">"<xliff:g id="VOLUME_RINGER_STATUS">%1$s</xliff:g>: докоснете, за да промените режима на звънене"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"спиране"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"пускане"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вибриране"</string>
@@ -1482,6 +1485,7 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Натиснете клавиша за действия на клавиатурата си"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Браво!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Изпълнихте жеста за преглед на всички приложения"</string>
+    <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Анимация за урока. Кликнете, за да поставите на пауза и да възобновите възпроизвеждането."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Подсветка на клавиатурата"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Ниво %1$d от %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Контроли за дома"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 8f5effc..8af32a8 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'বিরক্ত করবে না\' দিয়ে বিজ্ঞপ্তি পজ করা হয়েছে"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{কোনও বিজ্ঞপ্তি নেই}=1{{mode}-এর জন্য বিজ্ঞপ্তি পজ করা হয়েছে}=2{{mode} ও অন্য আরেকটি মোডের জন্য বিজ্ঞপ্তি পজ করা হয়েছে}one{{mode} ও অন্য #টি মোডের জন্য বিজ্ঞপ্তি পজ করা হয়েছে}other{{mode} ও অন্য #টি মোডের জন্য বিজ্ঞপ্তি পজ করা হয়েছে}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"এখন শুরু করুন"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"হেড ট্র্যাকিং"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"রিঙ্গার মোড পরিবর্তন করতে ট্যাপ করুন"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"রিঙ্গার মোড"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"মিউট করুন"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"আনমিউট করুন"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ভাইব্রেট করান"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"আপনার কীবোর্ডে অ্যাকশন কী প্রেস করুন"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"দারুণ!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"আপনি \'সব অ্যাপের জেসচার দেখুন\' টিউটোরিয়াল সম্পূর্ণ করেছেন"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"কীবোর্ড ব্যাকলাইট"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-এর মধ্যে %1$d লেভেল"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"হোম কন্ট্রোল"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 0a88d44..fe38ba8 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Da otvorite aplikaciju pomoću vidžeta, morat ćete potvrditi identitet. Također imajte na umu da ih svako može pregledati, čak i ako je tablet zaključan. Neki vidžeti možda nisu namijenjeni za vaš zaključani ekran i njihovo dodavanje ovdje možda nije sigurno."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Razumijem"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Vidžeti"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Da biste dodali prečac Widgeti, provjerite je li u postavkama omogućena opcija Prikaži widgete na zaključanom zaslonu."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Postavke"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zamijeni korisnika"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci iz ove sesije će se izbrisati."</string>
@@ -593,6 +591,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Obavještenja"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Razgovori"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Obriši sva nečujna obavještenja"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Obavještenja su pauzirana načinom rada Ne ometaj"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Nema obavještenja}=1{Obavještenja su pauzirana putem načina rada {mode}}=2{Obavještenja su pauzirana putem načina rada {mode} i još jednog načina rada}one{Obavještenja su pauzirana putem načina rada {mode} i još # načina rada}few{Obavještenja su pauzirana putem načina rada {mode} i još # načina rada}other{Obavještenja su pauzirana putem načina rada {mode} i još # načina rada}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Započni odmah"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Praćenje položaja glave"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da promijenite način rada zvuka zvona"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"način rada za zvuk zvona"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključite zvuk"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključite zvuk"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibriranje"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Prečice tastature"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodite prečice na tastaturi"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Ukloniti prečicu?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Želite li vratiti na zadano?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pritisnite tipku da dodijelite prečicu"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Ovo će trajno izbrisati prilagođenu prečicu."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Time će se trajno izbrisati svi vaši prilagođeni prečaci."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečica pretraživanja"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretraživanja"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona sužavanja"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Postavke tastature"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Postavi prečicu"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Ukloni"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Da, vrati na zadano"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Otkaži"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite tipku"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Ta se kombinacija tipki već koristi. Pokušajte s drugom tipkom."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pritisnite tipku radnji na tastaturi"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Odlično!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Izvršili ste pokret za prikaz svih aplikacija"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvjetljenje tastature"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. nivo od %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrole za dom"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 614fe23..ba3c4ad 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Per obrir una aplicació utilitzant un widget, necessitaràs verificar la teva identitat. També has de tenir en compte que qualsevol persona pot veure els widgets, fins i tot quan la tauleta està bloquejada. És possible que alguns widgets no estiguin pensats per a la pantalla de bloqueig i que no sigui segur afegir-los-hi."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entesos"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widgets"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Per afegir la drecera Widgets, assegura\'t que l\'opció Mostra els widgets a la pantalla de bloqueig estigui activada a la configuració."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Configuració"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Canvia d\'usuari"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú desplegable"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Totes les aplicacions i les dades d\'aquesta sessió se suprimiran."</string>
@@ -593,6 +591,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificacions"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Converses"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Esborra totes les notificacions silencioses"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificacions pausades pel mode No molestis"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{No hi ha cap notificació}=1{{mode} ha posat en pausa les notificacions}=2{{mode} i un altre mode han posat en pausa les notificacions}many{{mode} i # de modes més han posat en pausa les notificacions}other{{mode} i # modes més han posat en pausa les notificacions}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Comença ara"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Seguiment del cap"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Toca per canviar el mode de timbre"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"mode de timbre"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"deixar de silenciar"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Tecles de drecera"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalitza les tecles de drecera"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Vols suprimir la drecera?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Vols restablir els valors predeterminats?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Prem la tecla per assignar la drecera"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Aquesta acció suprimirà la drecera personalitzada permanentment."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Aquesta acció suprimirà totes les dreceres personalitzades permanentment."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Dreceres de cerca"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No hi ha cap resultat de la cerca"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Replega la icona"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configuració del teclat"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Configura la drecera"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Suprimeix"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Sí, restableix"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel·la"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Prem una tecla"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"La combinació de tecles ja s\'està utilitzant. Prova-ho amb una altra tecla."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Prem la tecla d\'acció al teclat"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Enhorabona!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Has completat el gest per veure totes les aplicacions"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroil·luminació del teclat"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivell %1$d de %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Controls de la llar"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 9d5a97a..317061f 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Oznámení"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzace"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Vymazat všechna tichá oznámení"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Oznámení jsou pozastavena režimem Nerušit"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Žádná oznámení}=1{Oznámení jsou pozastavená režimem {mode}}=2{Oznámení jsou pozastavená režimem {mode} a 1 dalším}few{Oznámení jsou pozastavená režimem {mode} a # dalšími}many{Oznámení jsou pozastavená režimem {mode} a # dalšího}other{Oznámení jsou pozastavená režimem {mode} a # dalšími}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Spustit"</string>
@@ -707,6 +709,8 @@
     <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_mode" msgid="6867838048430807128">"režim vyzvánění"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vypnout zvuk"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"zapnout zvuk"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrovat"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Stiskněte akční klávesu na klávesnici"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Výborně!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Provedli jste gesto k zobrazení všech aplikací"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podsvícení klávesnice"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Úroveň %1$d z %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Ovládání domácnosti"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 53f3462..3c0dc42 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifikationer"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Samtaler"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Ryd alle lydløse notifikationer"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifikationer er sat på pause af Forstyr ikke"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Ingen notifikationer}=1{Notifikationer er sat på pause af {mode}}=2{Notifikationer er sat på pause af {mode} og én anden tilstand}one{Notifikationer er sat på pause af {mode} og # anden tilstand}other{Notifikationer er sat på pause af {mode} og # andre tilstande}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start nu"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Hovedregistrering"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Tryk for at ændre ringetilstand"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"ringetilstand"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"slå lyden fra"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå lyden til"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrer"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tryk på handlingstasten på dit tastatur"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Flot klaret!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Du har udført bevægelsen for at se alle apps"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastaturets baggrundslys"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d af %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Hjemmestyring"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index e40445a..8d13524 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Benachrichtigungen"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Unterhaltungen"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Alle lautlosen Benachrichtigungen löschen"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Benachrichtigungen durch „Bitte nicht stören“ pausiert"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Keine Benachrichtigungen}=1{Benachrichtigungen durch {mode} pausiert}=2{Benachrichtigungen durch {mode} und einen weiteren Modus pausiert}other{Benachrichtigungen durch {mode} und # weitere Modi pausiert}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Jetzt starten"</string>
@@ -707,6 +709,8 @@
     <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_mode" msgid="6867838048430807128">"Klingeltonmodus"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"Stummschalten"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"Aufheben der Stummschaltung"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"Vibrieren lassen"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Drücke die Aktionstaste auf deiner Tastatur"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Perfekt!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Du hast das Tutorial für die Touch-Geste zum Aufrufen aller Apps abgeschlossen"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastaturbeleuchtung"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d von %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Smart-Home-Steuerung"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 43fa01a..b6de539 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Οι ειδοποιήσεις τέθηκαν σε παύση από τη λειτουργία \"Μην ενοχλείτε\""</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Δεν υπάρχουν ειδοποιήσεις}=1{Οι ειδοποιήσεις τέθηκαν σε παύση από τη λειτουργία {mode}}=2{Οι ειδοποιήσεις τέθηκαν σε παύση από τη λειτουργία {mode} και μία άλλη λειτουργία}other{Οι ειδοποιήσεις τέθηκαν σε παύση από τη λειτουργία {mode} και # άλλες λειτουργίες}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Έναρξη τώρα"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Παρακ. κίνησ. κεφαλής"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Πατήστε για να αλλάξετε τη λειτουργία ειδοποίησης ήχου"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"λειτουργία ειδοποίησης ήχου"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"σίγαση"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"κατάργηση σίγασης"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"δόνηση"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Πατήστε το πλήκτρο ενέργειας στο πληκτρολόγιό σας"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Μπράβο!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Ολοκληρώσατε την κίνηση για την προβολή όλων των εφαρμογών"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Οπίσθιος φωτισμός πληκτρολογίου"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Επίπεδο %1$d από %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Οικιακοί έλεγχοι"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index d32c95a..609e7af 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{No notifications}=1{Notifications paused by {mode}}=2{Notifications paused by {mode} and one other mode}other{Notifications paused by {mode} and # other modes}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Head tracking"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"ringer mode"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Press the action key on your keyboard"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Well done!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"You completed the view all apps gesture"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Home controls"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 8a7420d..be4e81f 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -591,6 +591,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
+    <string name="accessibility_notification_section_header_open_settings" msgid="6235202417954844004">"Open notifications settings"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{No notifications}=1{Notifications paused by {mode}}=2{Notifications paused by {mode} and one other mode}other{Notifications paused by {mode} and # other modes}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
@@ -705,6 +706,7 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Head Tracking"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"ringer mode"</string>
+    <string name="volume_ringer_drawer_closed_content_description" msgid="4737792429808781745">"<xliff:g id="VOLUME_RINGER_STATUS">%1$s</xliff:g>, tap to change ringer mode"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string>
@@ -1434,8 +1436,7 @@
     <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Action or Meta key icon"</string>
     <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plus icon"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Customize"</string>
-    <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
-    <skip />
+    <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Reset"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Done"</string>
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
@@ -1477,6 +1478,7 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Press the action key on your keyboard"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Well done!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"You completed the view all apps gesture"</string>
+    <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Tutorial animation, click to pause and resume play."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Home Controls"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index d32c95a..609e7af 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{No notifications}=1{Notifications paused by {mode}}=2{Notifications paused by {mode} and one other mode}other{Notifications paused by {mode} and # other modes}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Head tracking"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"ringer mode"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Press the action key on your keyboard"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Well done!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"You completed the view all apps gesture"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Home controls"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index d32c95a..609e7af 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{No notifications}=1{Notifications paused by {mode}}=2{Notifications paused by {mode} and one other mode}other{Notifications paused by {mode} and # other modes}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Head tracking"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"ringer mode"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Press the action key on your keyboard"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Well done!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"You completed the view all apps gesture"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Home controls"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 711f771..177e690 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificaciones"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversaciones"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Borrar todas las notificaciones silenciosas"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificaciones pausadas por el modo \"No interrumpir\""</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{No hay notificaciones}=1{{mode} pausó las notificaciones}=2{{mode} y un modo más pausaron las notificaciones}many{{mode} y # de modos más pausaron las notificaciones}other{{mode} y # modos más pausaron las notificaciones}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Comenzar ahora"</string>
@@ -707,6 +709,7 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Monitoreo de cabeza"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Presiona para cambiar el modo de timbre"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"modo de timbre"</string>
+    <string name="volume_ringer_drawer_closed_content_description" msgid="4737792429808781745">"<xliff:g id="VOLUME_RINGER_STATUS">%1$s</xliff:g>, presiona para cambiar el modo de timbre"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"dejar de silenciar"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1482,6 +1485,7 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Presiona la tecla de acción en el teclado"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"¡Bien hecho!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Completaste el gesto para ver todas las apps"</string>
+    <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animación del instructivo. Haz clic para pausar y reanudar la reproducción."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación del teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Controles de la casa"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 4a94cdf..53289d1 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -306,7 +306,7 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Usar Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Conectado"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Compartir audio"</string>
-    <string name="quick_settings_bluetooth_device_audio_sharing_or_switch_active" msgid="8680997711431098238">"Permite compartir audio"</string>
+    <string name="quick_settings_bluetooth_device_audio_sharing_or_switch_active" msgid="8680997711431098238">"Admite Compartir audio"</string>
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Guardado"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activar"</string>
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir una aplicación usando un widget, deberás verificar que eres tú. Además, ten en cuenta que cualquier persona podrá verlos, incluso aunque tu tablet esté bloqueada. Es posible que algunos widgets no estén pensados para la pantalla de bloqueo y no sea seguro añadirlos aquí."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendido"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widgets"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Para añadir el acceso directo Widgets, asegúrate de que la opción Mostrar widgets en la pantalla de bloqueo esté habilitada en los ajustes."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Ajustes"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar de usuario"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú desplegable"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán todas las aplicaciones y datos de esta sesión."</string>
@@ -593,6 +591,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificaciones"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversaciones"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Borrar todas las notificaciones silenciosas"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificaciones pausadas por el modo No molestar"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{No hay notificaciones}=1{Notificaciones pausadas por {mode}}=2{Notificaciones pausadas por {mode} y un modo más}many{Notificaciones pausadas por {mode} y # modos más}other{Notificaciones pausadas por {mode} y # modos más}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Empezar ahora"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Seguimiento de cabeza"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Toca para cambiar el modo de timbre"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"modo de timbre"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"dejar de silenciar"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar las combinaciones de teclas"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"¿Eliminar combinación de teclas?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"¿Restablecer valores predeterminados?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pulsa una tecla para asignar una combinación de teclas"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Se eliminará tu combinación de teclas personalizada de forma permanente."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Se eliminarán todos tus accesos directos personalizados de forma permanente."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atajos de búsqueda"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No hay resultados de búsqueda"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icono de contraer"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Ajustes del teclado"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Establecer combinación de teclas"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Eliminar"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Sí, restablecer"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pulsa una tecla"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"La combinación de teclas ya se está usando. Prueba con otra tecla."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pulsa la tecla de acción de tu teclado"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"¡Muy bien!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Has completado el gesto para ver todas las aplicaciones"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación del teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Controles de la casa"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 4027bbd..165f9c2 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Märguanded"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Vestlused"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Kustuta kõik hääletud märguanded"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Režiim Mitte segada peatas märguanded"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Märguandeid pole}=1{{mode} peatas märguanded}=2{{mode} ja veel üks režiim peatasid märguanded}other{{mode} ja veel # režiimi peatasid märguanded}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Alusta kohe"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Pea jälgimine"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Puudutage telefonihelina režiimi muutmiseks"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"telefonihelina režiim"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vaigistamine"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"vaigistuse tühistamine"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibreerimine"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Vajutage klaviatuuril toiminguklahvi"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Hästi tehtud!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Tegite kõigi rakenduste vaatamise liigutuse"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatuuri taustavalgustus"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Tase %1$d/%2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Kodu juhtelemendid"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index a0ba1b7..46bbdc3 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Jakinarazpenak"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Elkarrizketak"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Garbitu soinurik gabeko jakinarazpen guztiak"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ez molestatzeko moduak pausatu egin ditu jakinarazpenak"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Ez dago jakinarazpenik}=1{Modu honek jakinarazpenak pausatu ditu: {mode}}=2{Modu honek eta beste modu batek jakinarazpenak pausatu dituzte: {mode}}other{Modu honek eta beste # moduk jakinarazpenak pausatu dituzte: {mode}}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Hasi"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Buruaren jarraipena"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Sakatu tonu-jotzailearen modua aldatzeko"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"tonu-jotzailearen modua"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desaktibatu audioa"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktibatu audioa"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"dardara"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Sakatu teklatuko ekintza-tekla"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bikain!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Osatu duzu aplikazio guztiak ikusteko keinua"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Teklatuaren hondoko argia"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d/%2$d maila"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Etxeko gailuen kontrola"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 7bd01bc..5e68a95c 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"اعلان‌ها توسط «مزاحم نشوید» موقتاً متوقف شدند"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{اعلانی موقتاً متوقف نشده است}=1{اعلان‌ها را «{mode}» موقتاً متوقف کرده است}=2{اعلان‌ها را «{mode}» و یک حالت دیگر موقتاً متوقف کرد‌اند}one{اعلان‌ها را «{mode}» و # حالت دیگر موقتاً متوقف کرده‌اند}other{اعلان‌ها را «{mode}» و # حالت دیگر موقتاً متوقف کرده‌اند}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"اکنون شروع کنید"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ردیابی سر"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"برای تغییر حالت زنگ، تک‌ضرب بزنید"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"حالت زنگ"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"صامت کردن"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"باصدا کردن"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"لرزش"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"دکمه کنش را روی صفحه لمسی فشار دهید"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"عالی بود!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"اشاره «مشاهده همه برنامه‌ها» را تمام کردید"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"نور پس‌زمینه صفحه‌کلید"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"‏سطح %1$d از %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"کنترل خانه هوشمند"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index e617451..94b6364 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Jos haluat avata sovelluksen käyttämällä widgetiä, sinun täytyy vahvistaa henkilöllisyytesi. Muista myös, että widgetit näkyvät kaikille, vaikka tabletti olisi lukittuna. Jotkin widgetit on ehkä tarkoitettu lukitusnäytölle, ja niiden lisääminen tänne ei välttämättä ole turvallista."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Selvä"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widgetit"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Jos haluat lisätä Widgetit-pikakuvakkeen, varmista, että \"Näytä widgetit lukitusnäytöllä\" on käytössä asetuksissa."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Asetukset"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Vaihda käyttäjää"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"alasvetovalikko"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Kaikki sovellukset ja tämän istunnon tiedot poistetaan."</string>
@@ -593,6 +591,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Ilmoitukset"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Keskustelut"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Tyhjennä kaikki hiljaiset ilmoitukset"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Älä häiritse ‑tila keskeytti ilmoitukset"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Ei ilmoituksia}=1{{mode} keskeytti ilmoitukset}=2{{mode} ja yksi muu tila keskeytti ilmoitukset}other{{mode} ja # muuta tilaa keskeytti ilmoitukset}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Aloita nyt"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Pään seuranta"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Vaihda soittoäänen tilaa napauttamalla"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"Soittoäänen tila"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mykistä"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"poista mykistys"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"värinä"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Pikanäppäimet"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pikanäppäimien muokkaaminen"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Poistetaanko pikanäppäin?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Palautetaanko oletusasetukset?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Määritä pikanäppäin painamalla näppäintä"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Oma pikanäppäin poistetaan pysyvästi."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Kaikki omat pikanäppäimet poistetaan pysyvästi."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pikahaut"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ei hakutuloksia"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Tiivistyskuvake"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Näppäimistön asetukset"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Valitse pikanäppäin"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Poista"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Kyllä, nollaa"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Peru"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Paina näppäintä"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Näppäinyhdistelmä on jo käytössä. Kokeile toista näppäintä."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Paina näppäimistön toimintonäppäintä"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Hienoa!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Olet oppinut Näytä kaikki sovellukset ‑eleen."</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Näppämistön taustavalo"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Taso %1$d/%2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Kodin ohjaus"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 6213dd5..ea9ee0b 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Effacer toutes les notifications silencieuses"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Les notifications sont suspendues par le mode Ne pas déranger"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Aucune notification}=1{Notifications suspendues par {mode}}=2{Notifications suspendues par {mode} et un autre mode}one{Notifications suspendues par {mode} et # autre mode}many{Notifications suspendues par {mode} et # d\'autres modes}other{Notifications suspendues par {mode} et # autres modes}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Suivi de la tête"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Touchez pour modifier le mode de sonnerie"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"mode de sonnerie"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"désactiver le son"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"réactiver le son"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibration"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Appuyez sur la touche d\'action de votre clavier"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Félicitations!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Vous avez appris le geste pour afficher toutes les applis"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Rétroéclairage du clavier"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d de %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Domotique"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index d0931a6..bda70d9 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Effacer toutes les notifications silencieuses"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications suspendues par le mode Ne pas déranger"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Aucune notification}=1{Notifications suspendues par le mode {mode}}=2{Notifications suspendues par le mode {mode} et un autre mode}one{Notifications suspendues par le mode {mode} et # autre mode}many{Notifications suspendues par le mode {mode} et # d\'autres modes}other{Notifications suspendues par le mode {mode} et # autres modes}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
@@ -707,6 +709,8 @@
     <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_mode" msgid="6867838048430807128">"mode de sonnerie"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <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>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"activer le vibreur"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Appuyez sur la touche d\'action de votre clavier"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bravo !"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Vous avez appris le geste pour afficher toutes les applis"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Rétroéclairage du clavier"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d sur %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Contrôle de la maison"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index a02206d..53c4417 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificacións"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Borrar todas as notificacións silenciadas"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"O modo Non molestar puxo en pausa as notificacións"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Non hai ningunha notificación}=1{Notificacións postas en pausa polo modo {mode}}=2{Notificacións postas en pausa polo modo {mode} e un máis}other{Notificacións postas en pausa polo modo {mode} e # máis}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Seguimento da cabeza"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Toca para cambiar o modo de timbre"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"modo de timbre"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"activar o son"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Preme a tecla de acción do teclado"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Ben feito!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Completaches o titorial do xesto de ver todas as aplicacións"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación do teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Controis domóticos"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 8cff7ff..8ff5717 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"વિજેટનો ઉપયોગ કરીને ઍપ ખોલવા માટે, તમારે એ ચકાસણી કરવાની જરૂર રહેશે કે આ તમે જ છો. તે ઉપરાંત, ધ્યાનમાં રાખો કે તમારું ટૅબ્લેટ લૉક કરેલું હોય તો પણ કોઈપણ વ્યક્તિ તેમને જોઈ શકે છે. અમુક વિજેટ કદાચ તમારી લૉક સ્ક્રીન માટે બનાવવામાં આવ્યા ન હોઈ શકે છે અને તેમને અહીં ઉમેરવાનું અસલામત હોઈ શકે છે."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"સમજાઈ ગયું"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"વિજેટ"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"વિજેટ\"નો શૉર્ટકટ ઉમેરવા માટે, ખાતરી કરો કે સેટિંગમાં \"લૉક સ્ક્રીન પર વિજેટ બતાવો\" સુવિધા ચાલુ કરેલી છે."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"સેટિંગ"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ખલેલ પાડશો નહીં દ્વારા થોભાવેલ નોટિફિકેશન"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{કોઈ નોટિફિકેશન નથી}=1{{mode} દ્વારા નોટિફિકેશન થોભાવવામાં આવ્યા}=2{{mode} અને અન્ય એક મોડ દ્વારા નોટિફિકેશન થોભાવવામાં આવ્યા}one{{mode} અને અન્ય # મોડ દ્વારા નોટિફિકેશન થોભાવવામાં આવ્યા}other{{mode} અને અન્ય # મોડ દ્વારા નોટિફિકેશન થોભાવવામાં આવ્યા}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"હવે શરૂ કરો"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"હૅડ ટ્રૅકિંગ"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"રિંગર મોડ બદલવા માટે ટૅપ કરો"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"રિંગર મોડ"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"મ્યૂટ કરો"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"અનમ્યૂટ કરો"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"વાઇબ્રેટ"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"કીબોર્ડ શૉર્ટકટ"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"કીબોર્ડ શૉર્ટકટને કસ્ટમાઇઝ કરો"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"શું શૉર્ટકટ કાઢી નાખીએ?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"પાછા ડિફૉલ્ટ પર રીસેટ કરીએ?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"શૉર્ટકટ સોંપવા માટે કી દબાવો"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"આ તમારા કસ્ટમ શૉર્ટકટને કાયમી રીતે ડિલીટ કરશે."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"આ તમારા બધા કસ્ટમ શૉર્ટકટને કાયમ માટે ડિલીટ કરશે."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"શૉર્ટકટ શોધો"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"કોઈ શોધ પરિણામો નથી"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"\'નાનું કરો\'નું આઇકન"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"કીબોર્ડના સેટિંગ"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"શૉર્ટકટ સેટ કરો"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"કાઢી નાખો"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"હા, રીસેટ કરો"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"રદ કરો"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"કી દબાવો"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"કી સંયોજન પેહલેથી ઉપયોગમાં છે. અન્ય કી અજમાવી જુઓ."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"તમારા કીબોર્ડ પરની ઍક્શન કી દબાવો"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"વાહ!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"તમે \'બધી ઍપ જુઓ\' સંકેત પૂર્ણ કર્યો"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"કીબોર્ડની બૅકલાઇટ"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dમાંથી %1$d લેવલ"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ઘરેલું સાધનોના નિયંત્રણો"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 474014c..d2f6e5a 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'परेशान न करें\' सुविधा के ज़रिए कुछ समय के लिए सूचनाएं दिखाना रोक दिया गया है"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{कोई सूचना नहीं है}=1{{mode} की वजह से सूचना नहीं दिख रही है}=2{{mode} और एक अन्य मोड की वजह से सूचना नहीं दिख रही है}one{{mode} और # अन्य मोड की वजह से सूचना नहीं दिख रही है}other{{mode} और # अन्य मोड के की वजह से सूचनाएं नहीं दिख रही है}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"अभी शुरू करें"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"हेड ट्रैकिंग चालू है"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"रिंगर मोड बदलने के लिए टैप करें"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"रिंगर मोड"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्यूट करें"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"अनम्यूट करें"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"वाइब्रेशन की सुविधा चालू करें"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"अपने कीबोर्ड पर ऐक्शन बटन दबाएं"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"बहुत खूब!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"अब आपको हाथ के जेस्चर का इस्तेमाल करके, सभी ऐप्लिकेशन देखने का तरीका पता चल गया है"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"कीबोर्ड की बैकलाइट"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d में से %1$d लेवल"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"होम कंट्रोल"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 35996ea1..e566e4e 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Da biste otvorili aplikaciju pomoću widgeta, trebate potvrditi da ste to vi. Također napominjemo da ih svatko može vidjeti, čak i ako je vaš tablet zaključan. Neki widgeti možda nisu namijenjeni za zaključani zaslon, pa ih možda nije sigurno dodati ovdje."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Shvaćam"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widgeti"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Da biste dodali prečac Widgeti, provjerite je li u postavkama omogućena opcija Prikaži widgete na zaključanom zaslonu."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Postavke"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Promjena korisnika"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući izbornik"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Izbrisat će se sve aplikacije i podaci u ovoj sesiji."</string>
@@ -593,6 +591,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Obavijesti"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Razgovori"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Izbriši sve bešumne obavijesti"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Značajka Ne uznemiravaj pauzirala je Obavijesti"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Nema obavijesti}=1{Obavijesti je pauzirao način {mode}}=2{Obavijesti su pauzirali način {mode} i još jedan način}one{Obavijesti su pauzirali način {mode} i još # način rada}few{Obavijesti su pauzirali način {mode} i još # načina rada}other{Obavijesti su pauzirali način {mode} i još # načina rada}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Pokreni"</string>
@@ -707,6 +707,8 @@
     <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_mode" msgid="6867838048430807128">"način softvera zvona"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključivanje zvuka"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključivanje zvuka"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibriranje"</string>
@@ -859,7 +861,7 @@
     <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Prikazuju se prečaci za trenutačnu aplikaciju"</string>
     <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Prikaz obavijesti"</string>
     <string name="group_system_full_screenshot" msgid="5742204844232667785">"Snimanje zaslona"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Prikaži prečace"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Prikaz prečaca"</string>
     <string name="group_system_go_back" msgid="2730322046244918816">"Natrag"</string>
     <string name="group_system_access_home_screen" msgid="4130366993484706483">"Otvaranje početnog zaslona"</string>
     <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Prikaz nedavnih aplikacija"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Tipkovni prečaci"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodba tipkovnih prečaca"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Želite li ukloniti prečac?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Želite li vratiti na zadano?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pritisnite tipku da biste dodijelili prečac"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Time će se vaš prilagođeni prečac trajno izbrisati."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Time će se trajno izbrisati svi vaši prilagođeni prečaci."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečaci za pretraživanje"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretraživanja"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za sažimanje"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Postavke tipkovnice"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Postavite prečac"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Ukloni"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Da, vrati na zadano"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Odustani"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite tipku"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinacija tipki već se upotrebljava. Pokušajte s drugom tipkom."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pritisnite tipku za radnju na tipkovnici"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Izvrsno!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Napravili ste pokret za prikaz svih aplikacija"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvjetljenje tipkovnice"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Razina %1$d od %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Upravljanje uređajima"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index c807aee..0cbf0aa 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Értesítések"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Beszélgetések"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Az összes néma értesítés törlése"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ne zavarjanak funkcióval szüneteltetett értesítések"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Nincs értesítés}=1{A(z) {mode} szüneteltette az értesítéseket}=2{A(z) {mode} és egy másik mód szüneteltette az értesítéseket}other{A(z) {mode} és # másik mód szüneteltette az értesítéseket}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Indítás most"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Fejkövetés"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Koppintson a csengés módjának módosításához"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"csengés módja"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"némítás"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"némítás feloldása"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"rezgés"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Nyomja meg a műveletbillentyűt az érintőpadon."</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Szép munka!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Teljesítette az összes alkalmazás megtekintésének kézmozdulatát."</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"A billentyűzet háttérvilágítása"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Fényerő: %2$d/%1$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Otthon vezérlése"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 5603aff..867e0da 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ծանուցումները չեն ցուցադրվի «Չանհանգստացնել» ռեժիմում"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Ծանուցումներ չկան}=1{Ծանուցումները դադարեցվել են «{mode}» ռեժիմի կողմից}=2{Ծանուցումները դադարեցվել են «{mode}» ու ևս մի ռեժիմի կողմից}one{Ծանուցումները դադարեցվել են «{mode}» ու ևս # ռեժիմի կողմից}other{Ծանուցումները դադարեցվել են «{mode}» ու ևս # ռեժիմի կողմից}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Սկսել հիմա"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Գլխի շարժումների հետագծում"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Հպեք՝ զանգակի ռեժիմը փոխելու համար"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"զանգակի ռեժիմ"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"անջատել ձայնը"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"միացնել ձայնը"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"միացնել թրթռոցը"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Սեղմեք գործողության ստեղնը ստեղնաշարի վրա"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Հիանալի՛ է"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Դուք սովորեցիք բոլոր հավելվածները դիտելու ժեստը"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Հետին լուսավորությամբ ստեղնաշար"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d՝ %2$d-ից"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Տան կառավարման տարրեր"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 3820ab7..06ecd11 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifikasi"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Percakapan"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Hapus semua notifikasi senyap"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifikasi dijeda oleh mode Jangan Ganggu"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Tidak ada notifikasi}=1{Notifikasi dijeda oleh {mode}}=2{Notifikasi dijeda oleh {mode} dan satu mode lainnya}other{Notifikasi dijeda oleh {mode} dan # mode lainnya}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Mulai sekarang"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Pelacakan Gerak Kepala"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Ketuk untuk mengubah mode pendering"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"mode pendering"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"Tanpa suara"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktifkan"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"getar"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tekan tombol tindakan di keyboard"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Oke!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Anda telah menyelesaikan gestur untuk melihat semua aplikasi"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Lampu latar keyboard"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Tingkat %1$d dari %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrol Rumah"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 931c3dc..4f6ff47 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Þú þarft að staðfesta að þetta sért þú til að geta opnað forrit með græju. Hafðu einnig í huga að hver sem er getur skoðað þær, jafnvel þótt spjaldtölvan sé læst. Sumar græjur eru hugsanlega ekki ætlaðar fyrir lásskjá og því gæti verið óöruggt að bæta þeim við hér."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ég skil"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Græjur"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Gakktu úr skugga um að kveikt sé á „Sýna græjur á lásskjá“ til að geta bætt flýtileiðinni „Græjur“ við."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Stillingar"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skipta um notanda"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"Fellivalmynd"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Öllum forritum og gögnum í þessari lotu verður eytt."</string>
@@ -593,6 +591,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Tilkynningar"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Samtöl"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Hreinsa allar þöglar tilkynningar"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Hlé gert á tilkynningum þar sem stillt er á „Ónáðið ekki“"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Engar tilkynningar}=1{Hlé gert á tilkynningum þar sem stillt er á {mode}}=2{Hlé gert á tilkynningum þar sem stillt er á {mode} og eina aðra stillingu}one{Hlé gert á tilkynningum þar sem stillt er á {mode} og # aðra stillingu}other{Hlé gert á tilkynningum þar sem stillt er á {mode} og # aðrar stillingar}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Byrja núna"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Rakning höfuðhreyfinga"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Ýta til að skipta um hringjarastillingu"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"hringistilling"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"þagga"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"hætta að þagga"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"titringur"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Flýtilyklar"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sérsníddu flýtilykla"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Fjarlægja flýtileið?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Endurstilla á sjálfgefið?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Ýttu á lykil til að stilla flýtileið"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Þetta eyðir sérsniðnu flýtileiðinni varanlega."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Þetta verður til þess að öllum sérsniðnu flýtileiðunum þínum verður eytt varanlega."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Leita að flýtileiðum"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Engar leitarniðurstöður"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Minnka tákn"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Stillingar lyklaborðs"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Stilltu flýtileið"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Fjarlægja"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Já, endurstilla"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Hætta við"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Ýttu á lykil"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Lyklasamsetningin er þegar í notkun. Prófaðu annan lykil."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Ýttu á aðgerðalykilinn á lyklaborðinu"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Vel gert!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Þú framkvæmdir bendinguna „Sjá öll forrit“"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Baklýsing lyklaborðs"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Stig %1$d af %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Heimastýringar"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 7c2fc4f..76e3360 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Per aprire un\'app utilizzando un widget, dovrai verificare la tua identità. Inoltre tieni presente che chiunque può vederlo, anche quando il tablet è bloccato. Alcuni widget potrebbero non essere stati progettati per la schermata di blocco e potrebbe non essere sicuro aggiungerli qui."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ok"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widget"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Per aggiungere la scorciatoia \"Widget\", assicurati che l\'opzione \"Mostra widget sulla schermata di blocco\" sia abilitata nelle impostazioni."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Impostazioni"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambio utente"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu a discesa"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tutte le app e i dati di questa sessione verranno eliminati."</string>
@@ -593,6 +591,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifiche"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversazioni"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Cancella tutte le notifiche silenziose"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifiche messe in pausa in base alla modalità Non disturbare"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Nessuna notifica}=1{Notifica messa in pausa da {mode}}=2{Notifiche messe in pausa da {mode} e un\'altra modalità}many{Notifiche messe in pausa da {mode} e # di modalità}other{Notifiche messe in pausa da {mode} e altre # modalità}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Avvia adesso"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Rilev. movim. testa"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Tocca per cambiare la modalità della suoneria"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"modalità suoneria"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenzia"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"riattiva l\'audio"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrazione"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Scorciatoie da tastiera"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizza scorciatoie da tastiera"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Rimuovere scorciatoia?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Vuoi ripristinare il valore predefinito?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Premi un tasto per assegnare una scorciatoia"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"La scorciatoia personalizzata verrà eliminata definitivamente."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Tutte le tue scorciatoie personalizzate verranno eliminate definitivamente."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Scorciatoie per la ricerca"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nessun risultato di ricerca"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icona Comprimi"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Impostazioni tastiera"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Imposta scorciatoia"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Rimuovi"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Sì, ripristina"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annulla"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Premi un tasto"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Combinazione di tasti già in uso. Prova con un altro tasto."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Premi il tasto azione sulla tastiera"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Ben fatto!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Hai completato il gesto Visualizza tutte le app."</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroilluminazione della tastiera"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Livello %1$d di %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Controlli della casa"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index e481a77..3257e14 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"התראות הושהו על ידי מצב \'נא לא להפריע\'"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{אין התראות}=1{ההתראות הושהו על ידי {mode}}=2{ההתראות הושהו על ידי {mode} ועל ידי מצב אחד נוסף}one{ההתראות הושהו על ידי {mode} ועל ידי # מצבים נוספים}other{ההתראות הושהו על ידי {mode} ועל ידי # מצבים נוספים}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"כן, אפשר להתחיל"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"מעקב ראש"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"יש להקיש כדי לשנות את מצב תוכנת הצלצול"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"מצב תוכנת הצלצול"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"השתקה"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ביטול ההשתקה"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"רטט"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"צריך להקיש על מקש הפעולה במקלדת"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"כל הכבוד!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"סיימת לתרגל את התנועה להצגת כל האפליקציות"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"התאורה האחורית במקלדת"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"‏רמה %1$d מתוך %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"שליטה במכשירים"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 1a2d022..13dd954 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ウィジェットを使用してアプリを起動するには、本人確認が必要です。タブレットがロックされた状態でも他のユーザーにウィジェットが表示されますので、注意してください。一部のウィジェットについてはロック画面での使用を想定していないため、ロック画面への追加は危険な場合があります。"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"ウィジェット"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"[ウィジェット] ショートカットを追加するには、設定で [ロック画面でのウィジェットの表示] が有効になっていることを確認してください。"</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"設定"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"サイレント モードにより通知は一時停止中です"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{通知なし}=1{{mode} により通知は一時停止中です}=2{{mode} と他 1 個のモードにより通知は一時停止中です}other{{mode} と他 # 個のモードにより通知は一時停止中です}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"今すぐ開始"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ヘ⁠ッ⁠ド ト⁠ラ⁠ッ⁠キ⁠ン⁠グ"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"タップすると、着信音のモードを変更できます"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"着信音のモード"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ミュート"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ミュートを解除"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"バイブレーション"</string>
@@ -1426,20 +1428,17 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"キーボード ショートカット"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"キーボード ショートカットをカスタマイズする"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"ショートカットを削除しますか?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"デフォルトにリセットしますか?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"ショートカットを割り当てるキーを押してください"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"この操作を行うと、カスタム ショートカットが完全に削除されます。"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"この操作を行うと、すべてのカスタム ショートカットが完全に削除されます。"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"検索ショートカット"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"検索結果がありません"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"閉じるアイコン"</string>
     <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"アクションキーまたはメタキーのアイコン"</string>
     <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"プラスアイコン"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"カスタマイズ"</string>
-    <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
-    <skip />
+    <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"リセット"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"完了"</string>
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"開くアイコン"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"または"</string>
@@ -1449,8 +1448,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"キーボードの設定"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ショートカットの設定"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"削除"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"リセットする"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"キャンセル"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"キーを押してください"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"このキーの組み合わせはすでに使用されています。別のキーを試してください。"</string>
@@ -1482,6 +1480,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"キーボードのアクションキーを押します"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"完了です!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"「すべてのアプリを表示する」ジェスチャーを学習しました"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"キーボード バックライト"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"レベル %1$d/%2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ホーム コントロール"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index d7fe284..9390bd2 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"უნდა დაადასტუროთ თქვენი ვინაობა, რათა გახსნათ აპი ვიჯეტის გამოყენებით. გაითვალისწინეთ, რომ ნებისმიერს შეუძლია მათი ნახვა, მაშინაც კი, როცა ტაბლეტი დაბლოკილია. ზოგი ვიჯეტი შეიძლება არ იყოს გათვლილი თქვენი დაბლოკილი ეკრანისთვის და მათი აქ დამატება შეიძლება სახიფათო იყოს."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"გასაგებია"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"ვიჯეტები"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"„ვიჯეტების“ მალსახმობის დასამატებლად დარწმუნდით, რომ პარამეტრებში ჩართულია „დაბლოკილ ეკრანზე ვიჯეტების ჩვენება“."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"პარამეტრები"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"შეტყობინებები დაპაუზდა „არ შემაწუხოთ“ რეჟიმის მეშვეობით"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{შეტყობინებები არ არის}=1{შეტყობინებები შეჩერებულია {mode}-ის გამო}=2{შეტყობინებები შეჩერებულია {mode}-ის და ერთი სხვა რეჟიმის გამო}other{შეტყობინებები შეჩერებულია {mode}-ის და # სხვა რეჟიმის გამო}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"დაწყება ახლავე"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ხმის მიდევნებით"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"შეეხეთ მრეკავის რეჟიმის შესაცვლელად"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"მრეკავის რეჟიმი"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"დადუმება"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"დადუმების მოხსნა"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ვიბრაცია"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"კლავიატურის მალსახმობები"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"კლავიატურის მალსახმობების მორგება"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"გსურთ მალსახმობის წაშლა?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"გსურთ ნაგულისხმევზე გადაყენება?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"მალსახმობის მინიჭებისთვის დააჭირეთ კლავიშს"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"ეს თქვენს მორგებულ მალსახმობებს სამუდამოდ წაშლის."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"ეს სამუდამოდ წაშლის თქვენს ყველა მორგებულ მალსახმობს."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ძიების მალსახმობები"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ძიების შედეგები არ არის"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ხატულის ჩაკეცვა"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"კლავიატურის პარამეტრები"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"მალსახმობის დაყენება"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"ამოშლა"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"დიახ, გადაყენდეს"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"გაუქმება"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"დააჭირეთ კლავიშს"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"კლავიშების კომბინაცია უკვე გამოიყენება. ცადეთ სხვა კლავიში."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"დააჭირეთ მოქმედების კლავიშს თქვენს კლავიატურაზე"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ყოჩაღ!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"თქვენ დაასრულეთ ყველა აპის ნახვის ჟესტი"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"კლავიატურის შენათება"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"დონე: %1$d %2$d-დან"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"სახლის კონტროლი"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 92269a2..672bb66 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Қолданбаны виджет көмегімен ашу үшін жеке басыңызды растауыңыз керек. Сондай-ақ басқалар оларды планшетіңіз құлыптаулы кезде де көре алатынын ескеріңіз. Кейбір виджеттер құлып экранына арналмаған болады, сондықтан оларды мұнда қосу қауіпсіз болмауы мүмкін."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Түсінікті"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Виджеттер"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"Виджеттер\" таңбашасын қосу үшін параметрлерде \"Виджеттерді құлыптаулы экранда көрсету\" опциясының қосулы екенін тексеріңіз."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Параметрлер"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Хабарландырулар Мазаламау режимінде кідіртілді"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Хабарландырулар жоқ.}=1{Хабарландыруларды {mode} режимі кідіртті.}=2{Хабарландыруларды {mode} және тағы бір режим кідіртті.}other{Хабарландыруларды {mode} және тағы # режим кідіртті.}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Қазір бастау"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Бас қимылын қадағалау"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Қоңырау режимін өзгерту үшін түртіңіз."</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"қоңырау режимі"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"дыбысын өшіру"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"дыбысын қосу"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"дірілдету"</string>
@@ -1426,20 +1428,17 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Перне тіркесімдері"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Пернелер тіркесімін бейімдеу"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Жылдам пәрменді өшіру керек пе?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Әдепкі таңбашаларға қайтару керек пе?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Жылдам пәрменді тағайындау үшін пернені басыңыз."</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Арнаулы жылдам пәрменіңіз біржола жойылады."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Мұндайда барлық арнаулы таңбашалар біржола жойылады."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Іздеу жылдам пәрмендері"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Іздеу нәтижелері жоқ."</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жию белгішесі"</string>
     <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Әрекет немесе Meta пернесінің белгішесі"</string>
     <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Қосу белгішесі"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Бейімдеу"</string>
-    <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
-    <skip />
+    <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Бастапқы күйге қайтару"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Дайын"</string>
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Жаю белгішесі"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"немесе"</string>
@@ -1449,8 +1448,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Пернетақта параметрлері"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Жылдам пәрменді орнату"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Өшіру"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Иә, қайтару"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Бас тарту"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Пернені басыңыз"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Бұл пернелер тіркесімі қазір қолданыста. Басқа перне таңдаңыз."</string>
@@ -1482,6 +1480,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Пернетақтадағы әрекет пернесін басыңыз."</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Жарайсыз!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Барлық қолданбаны көру қимылын орындадыңыз."</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Пернетақта жарығы"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Деңгей: %1$d/%2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Үй басқару элементтері"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 13153c6..96a9ed4 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ដើម្បីបើកកម្មវិធីដោយប្រើធាតុ​ក្រាហ្វិក អ្នកនឹងត្រូវផ្ទៀងផ្ទាត់ថាជាអ្នក។ ទន្ទឹមនឹងនេះ សូមចងចាំថា នរណាក៏អាចមើលធាតុក្រាហ្វិកបាន សូម្បីពេលថេប្លេតរបស់អ្នកជាប់សោក៏ដោយ។ ធាតុ​ក្រាហ្វិកមួយចំនួនប្រហែលមិនត្រូវបានរចនាឡើងសម្រាប់អេក្រង់ចាក់សោរបស់អ្នកទេ និងមិនមានសុវត្ថិភាពឡើយ បើបញ្ចូលទៅទីនេះ។"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"យល់ហើយ"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"ធាតុ​ក្រាហ្វិក"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"ដើម្បីបញ្ចូលផ្លូវកាត់ \"ធាតុ​ក្រាហ្វិក\" ត្រូវប្រាកដថា \"បង្ហាញធាតុ​ក្រាហ្វិកនៅលើអេក្រង់ចាក់សោ\" ត្រូវបានបើកនៅក្នុងការកំណត់។"</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"ការកំណត់"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ការជូនដំណឹង​បានផ្អាក​ដោយ​មុខងារកុំរំខាន"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{គ្មាន​ការជូន​ដំណឹង}=1{ការជូនដំណឹង​ត្រូវបាន​ផ្អាកដោយ {mode}}=2{ការជូនដំណឹង​ត្រូវបាន​ផ្អាកដោយ {mode} និង​មុខងារមួយ​ផ្សេងទៀត}other{ការជូនដំណឹង​ត្រូវបាន​ផ្អាកដោយ {mode} និង​មុខងារ # ផ្សេងទៀត}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ចាប់ផ្ដើម​ឥឡូវ"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"រេតាមក្បាល"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"ចុច​ដើម្បីប្ដូរ​មុខងារ​រោទ៍"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"មុខងារកម្មវិធី​រោទ៍"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"បិទ​សំឡេង"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"បើក​សំឡេង"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ញ័រ"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"ផ្លូវកាត់​ក្ដារ​ចុច"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ប្ដូរ​ផ្លូវកាត់​ក្ដារ​ចុចតាម​បំណង"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"ដក​ផ្លូវកាត់​ចេញឬ?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"កំណត់ឡើងវិញទៅលំនាំដើមឬ?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"ចុចគ្រាប់ចុច ដើម្បីកំណត់ផ្លូវ​កាត់"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"ការធ្វើបែបនេះនឹងលុបផ្លូវ​កាត់ផ្ទាល់ខ្លួនរបស់អ្នកជាអចិន្ត្រៃយ៍។"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"សកម្មភាពនេះនឹងលុបផ្លូវកាត់ផ្ទាល់ខ្លួនរបស់អ្នកទាំងអស់ជាអចិន្ត្រៃយ៍។"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ស្វែងរកផ្លូវ​កាត់"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"គ្មាន​លទ្ធផល​ស្វែងរក​ទេ"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"រូបតំណាង \"បង្រួម\""</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ការកំណត់​ក្ដារចុច"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"កំណត់ផ្លូវ​កាត់"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"ដកចេញ"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"បាទ/ចាស កំណត់ឡើងវិញ"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"បោះបង់"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ចុចគ្រាប់ចុច"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"កំពុងប្រើបន្សំគ្រាប់ចុចស្រាប់ហើយ។ សាកល្បងប្រើគ្រាប់ចុចផ្សេង។"</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ចុចគ្រាប់ចុចសកម្មភាពលើក្ដារចុចរបស់អ្នក"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ធ្វើបាន​ល្អ!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"អ្នកបានបញ្ចប់ចលនាមើលកម្មវិធីទាំងអស់ហើយ"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ពន្លឺក្រោយក្ដារចុច"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"កម្រិតទី %1$d នៃ %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ការគ្រប់គ្រង​ផ្ទះ"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index b83e957..89b8db2 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ವಿಜೆಟ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು ಆ್ಯಪ್ ತೆರೆಯಲು, ಇದು ನೀವೇ ಎಂದು ನೀವು ದೃಢೀಕರಿಸಬೇಕಾಗುತ್ತದೆ. ಅಲ್ಲದೆ, ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಲಾಕ್ ಆಗಿದ್ದರೂ ಸಹ ಯಾರಾದರೂ ಅವುಗಳನ್ನು ವೀಕ್ಷಿಸಬಹುದು ಎಂಬುದನ್ನು ನೆನಪಿನಲ್ಲಿಡಿ. ಕೆಲವು ವಿಜೆಟ್‌ಗಳು ನಿಮ್ಮ ಲಾಕ್ ಸ್ಕ್ರೀನ್‌ಗಾಗಿ ಉದ್ದೇಶಿಸದೇ ಇರಬಹುದು ಮತ್ತು ಇಲ್ಲಿ ಸೇರಿಸುವುದು ಸುರಕ್ಷಿತವಲ್ಲದಿರಬಹುದು."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ಅರ್ಥವಾಯಿತು"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"ವಿಜೆಟ್‌ಗಳು"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"ವಿಜೆಟ್‌ಗಳು\" ಶಾರ್ಟ್‌ಕಟ್ ಸೇರಿಸಲು, ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ \"ಲಾಕ್ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ವಿಜೆಟ್‌ಗಳನ್ನು ತೋರಿಸಿ\" ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಎನ್ನುವ ಮೂಲಕ ಅಧಿಸೂಚನೆಗಳನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{ಯಾವುದೇ ನೋಟಿಫಿಕೇಶನ್‌ಗಳು ಇಲ್ಲ}=1{ನೋಟಿಫಿಕೇಶನ್‌ಗಳನ್ನು {mode} ವಿರಾಮಗೊಳಿಸಿದೆ}=2{ನೋಟಿಫಿಕೇಶನ್‌ಗಳನ್ನು {mode} ಹಾಗೂ ಇತರ ಒಂದು ಮೋಡ್ ವಿರಾಮಗೊಳಿಸಿವೆ}one{ನೋಟಿಫಿಕೇಶನ್‌ಗಳನ್ನು {mode} ಹಾಗೂ ಇತರ # ಮೋಡ್‌ಗಳು ವಿರಾಮಗೊಳಿಸಿವೆ}other{ನೋಟಿಫಿಕೇಶನ್‌ಗಳನ್ನು {mode} ಹಾಗೂ ಇತರ # ಮೋಡ್‌ಗಳು ವಿರಾಮಗೊಳಿಸಿವೆ}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ಈಗ ಪ್ರಾರಂಭಿಸಿ"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ಹೆಡ್ ಟ್ರ್ಯಾಕಿಂಗ್"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"ರಿಂಗರ್ ಮೋಡ್ ಬದಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"ರಿಂಗರ್ ಮೋಡ್"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ಮ್ಯೂಟ್ ಮಾಡಿ"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ಅನ್‌ಮ್ಯೂಟ್ ಮಾಡಿ"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ವೈಬ್ರೇಟ್‌"</string>
@@ -1426,20 +1428,17 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"ಶಾರ್ಟ್‌ಕಟ್ ಅನ್ನು ತೆಗೆದುಹಾಕಬೇಕೇ?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ಡೀಫಾಲ್ಟ್‌ಗೆ ರೀಸೆಟ್ ಮಾಡಬೇಕೆ?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"ಶಾರ್ಟ್‌ಕಟ್ ಅನ್ನು ನಿಯೋಜಿಸಲು ಕೀಯನ್ನು ಒತ್ತಿರಿ"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"ಇದು ನಿಮ್ಮ ಕಸ್ಟಮ್ ಶಾರ್ಟ್‌ಕಟ್ ಅನ್ನು ಶಾಶ್ವತವಾಗಿ ಅಳಿಸುತ್ತದೆ."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"ಇದು ನಿಮ್ಮ ಎಲ್ಲಾ ಕಸ್ಟಮ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಶಾಶ್ವತವಾಗಿ ಅಳಿಸುತ್ತದೆ."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ಹುಡುಕಾಟದ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ಯಾವುದೇ ಹುಡುಕಾಟ ಫಲಿತಾಂಶಗಳಿಲ್ಲ"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ಕುಗ್ಗಿಸುವ ಐಕಾನ್"</string>
     <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ಆ್ಯಕ್ಷನ್ ಅಥವಾ ಮೆಟಾ ಕೀ ಐಕಾನ್"</string>
     <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ಪ್ಲಸ್ ಐಕಾನ್"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
-    <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
-    <skip />
+    <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"ರೀಸೆಟ್ ಮಾಡಿ"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ಮುಗಿದಿದೆ"</string>
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ವಿಸ್ತೃತಗೊಳಿಸುವ ಐಕಾನ್"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ಅಥವಾ"</string>
@@ -1449,8 +1448,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ಕೀಬೋರ್ಡ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ಶಾರ್ಟ್‌ಕಟ್ ಸೆಟ್ ಮಾಡಿ"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"ತೆಗೆದುಹಾಕಿ"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"ಹೌದು, ರೀಸೆಟ್ ಮಾಡಿ"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ರದ್ದುಮಾಡಿ"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ಕೀ ಅನ್ನು ಒತ್ತಿರಿ"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"ಕೀ ಸಂಯೋಜನೆಯು ಈಗಾಗಲೇ ಬಳಕೆಯಲ್ಲಿದೆ. ಮತ್ತೊಂದು ಕೀ ಬಳಸಿ ನೋಡಿ."</string>
@@ -1482,6 +1480,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ನಿಮ್ಮ ಕೀಬೋರ್ಡ್‌ನಲ್ಲಿ ಆ್ಯಕ್ಷನ್‌ ಕೀಯನ್ನು ಒತ್ತಿ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ಭೇಷ್!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ನೀವು ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳ ಜೆಸ್ಚರ್‌ ವೀಕ್ಷಣೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ಕೀಬೋರ್ಡ್ ಬ್ಯಾಕ್‌ಲೈಟ್"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ರಲ್ಲಿ %1$d ಮಟ್ಟ"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ಮನೆ ನಿಯಂತ್ರಣಗಳು"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 00b2450..276d708 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"위젯을 사용하여 앱을 열려면 본인 인증을 해야 합니다. 또한 태블릿이 잠겨 있더라도 누구나 볼 수 있다는 점을 유의해야 합니다. 일부 위젯은 잠금 화면에 적합하지 않고 여기에 추가하기에 안전하지 않을 수 있습니다."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"확인"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"위젯"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\'위젯\' 바로가기를 추가하려면 설정에서 \'잠금 화면에 위젯 표시\'가 사용 설정되어 있어야 합니다."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"설정"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"방해 금지 모드로 알림이 일시중지됨"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{알림 없음}=1{{mode} 모드로 인해 알림이 일시중지되었습니다.}=2{{mode} 및 다른 모드로 인해 알림이 일시중지되었습니다.}other{{mode} 및 다른 모드 #개로 인해 알림이 일시중지되었습니다.}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"시작하기"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"머리 추적"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"탭하여 벨소리 장치 모드 변경"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"벨소리 장치 모드"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"음소거"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"음소거 해제"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"진동"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"단축키"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"단축키 맞춤설정"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"바로가기를 제거하시겠습니까?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"기본값으로 재설정하시겠어요?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"키를 눌러 단축키 지정"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"맞춤 단축어가 영구적으로 삭제됩니다."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"모든 맞춤 바로가기가 완전히 삭제됩니다."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"검색 바로가기"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"검색 결과 없음"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"접기 아이콘"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"키보드 설정"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"단축키 설정"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"삭제"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"재설정"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"취소"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"키를 누르세요."</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"이미 사용 중인 키 조합입니다. 다른 키를 사용해 보세요."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"키보드의 작업 키를 누르세요."</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"잘하셨습니다"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"모든 앱 보기 동작을 완료했습니다."</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"키보드 백라이트"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d단계 중 %1$d단계"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"홈 컨트롤"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index a857f4e..ab20a7b 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Колдонмону виджет аркылуу ачуу үчүн өзүңүздү ырасташыңыз керек. Алар кулпуланган планшетиңизде да көрүнүп турат. Кээ бир виджеттерди кулпуланган экранда колдоно албайсыз, андыктан аларды ал жерге кошпой эле койгонуңуз оң."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Түшүндүм"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Виджеттер"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"Виджеттер\" ыкчам баскычын кошуу үчүн параметрлерге өтүп, \"Виджеттерди кулпуланган экранда көрсөтүү\" параметри иштетилгенин текшериңиз."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Параметрлер"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\"Тынчымды алба\" режиминде билдирмелер тындырылды"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Билдирмелер жок}=1{{mode} режими билдирмелерди тындырды}=2{{mode} жана дагы бир режим билдирмелерди тындырды}other{{mode} жана дагы # режим билдирмелерди тындырды}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Азыр баштоо"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Баштын кыймылына көз салуу"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Коңгуроо режимин өзгөртүү үчүн басыңыз"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"коңгуроо режими"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"үнсүз"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"үнүн чыгаруу"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"дирилдөө"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Ыкчам баскычтар"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Ыкчам баскычтарды ыңгайлаштыруу"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Ыкчам баскыч өчүрүлсүнбү?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Баштапкы абалга келтиресизби?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Ыкчам баскычты дайындоо үчүн баскычты басыңыз"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Ушуну менен жеке ыкчам баскычыңыз биротоло өчүрүлөт."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Ушуну менен жеке ыкчам баскычтарыңыздын баары биротоло өчүрүлөт."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Ыкчам баскычтарды издөө"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Эч нерсе табылган жок"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жыйыштыруу сүрөтчөсү"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Баскычтоп параметрлери"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ыкчам баскычты тууралоо"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Өчүрүү"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Ооба, баштапкы абалга келтирилсин"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Баскычты басыңыз"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Ачкычтардын айкалышы колдонулууда. Башка ачкычты байкап көрүңүз."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Баскычтобуңуздагы аракет баскычын басыңыз"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Эң жакшы!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Бардык колдонмолорду көрүү жаңсоосун аткардыңыз"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Баскычтоптун жарыгы"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ичинен %1$d-деңгээл"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Үйдөгү түзмөктөрдү тескөө"</string>
diff --git a/packages/SystemUI/res/values-land/styles.xml b/packages/SystemUI/res/values-land/styles.xml
index 73812c9..ae0006f 100644
--- a/packages/SystemUI/res/values-land/styles.xml
+++ b/packages/SystemUI/res/values-land/styles.xml
@@ -43,21 +43,21 @@
         <item name="android:layout_marginTop">6dp</item>
         <item name="android:textSize">36dp</item>
         <item name="android:focusable">true</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.AuthNonBioCredential.Subtitle">
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:layout_marginTop">6dp</item>
         <item name="android:textSize">18sp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.AuthNonBioCredential.Description">
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:layout_marginTop">6dp</item>
         <item name="android:textSize">18sp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 19b216d..a3a25e8 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ຢຸດການແຈ້ງເຕືອນໂດຍໂໝດຫ້າມລົບກວນແລ້ວ"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{ບໍ່ມີການແຈ້ງເຕືອນ}=1{{mode} ຢຸດການແຈ້ງເຕືອນໄວ້ຊົ່ວຄາວ}=2{{mode} ແລະ ອີກ 1 ໂໝດຢຸດການແຈ້ງເຕືອນໄວ້ຊົ່ວຄາວ}other{{mode} ແລະ ອີກ # ໂໝດຢຸດການແຈ້ງເຕືອນໄວ້ຊົ່ວຄາວ}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ເລີ່ມດຽວນີ້"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ການຕິດຕາມຫົວ"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"ແຕະເພື່ອປ່ຽນໂໝດຣິງເກີ"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"ໂໝດຣິງເກີ"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ປິດສຽງ"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ເຊົາປິດສຽງ"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ສັ່ນເຕືອນ"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ກົດປຸ່ມຄຳສັ່ງຢູ່ແປ້ນພິມຂອງທ່ານ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ດີຫຼາຍ!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ທ່ານເບິ່ງທ່າທາງຂອງແອັບທັງໝົດສຳເລັດແລ້ວ"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ໄຟປຸ່ມແປ້ນພິມ"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"ລະດັບທີ %1$d ຈາກ %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ການຄວບຄຸມເຮືອນ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 6d4c775..cba0db1 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Pranešimai"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Pokalbiai"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Išvalyti visus tylius pranešimus"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Pranešimai pristabdyti naudojant netrukdymo režimą"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Nėra pranešimų}=1{Pranešimai pristabdyti naudojant režimą „{mode}“}=2{Pranešimai pristabdyti naudojant režimą „{mode}“ ir dar vieną režimą}one{Pranešimai pristabdyti naudojant režimą „{mode}“ ir dar # režimą}few{Pranešimai pristabdyti naudojant režimą „{mode}“ ir dar # režimus}many{Pranešimai pristabdyti naudojant režimą „{mode}“ ir dar # režimo}other{Pranešimai pristabdyti naudojant režimą „{mode}“ ir dar # režimų}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Pradėti dabar"</string>
@@ -707,6 +709,7 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Galvos stebėjimas"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Palieskite, kad pakeistumėte skambučio režimą"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"skambučio režimas"</string>
+    <string name="volume_ringer_drawer_closed_content_description" msgid="4737792429808781745">"<xliff:g id="VOLUME_RINGER_STATUS">%1$s</xliff:g>, palieskite, kad pakeistumėte skambučio režimą"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"nutildyti"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"įjungti garsą"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibruoti"</string>
@@ -1482,6 +1485,7 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Paspauskite klaviatūros veiksmų klavišą"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Puikiai padirbėta!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Atlikote visų programų peržiūros gestą"</string>
+    <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Mokomoji animacija. Spustelėkite, kad pristabdytumėte ir tęstumėte atkūrimą."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatūros foninis apšvietimas"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d lygis iš %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Namų sistemos valdymas"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index d522946..7698008 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Paziņojumi"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Sarunas"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Notīrīt visus klusos paziņojumus"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Paziņojumi pārtraukti, izmantojot iestatījumu “Netraucēt”"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Nav paziņojumu}=1{Paziņojumu rādīšana ir pārtraukta režīma “{mode}” dēļ}=2{Paziņojumu rādīšana ir pārtraukta režīma “{mode}” un vēl viena režīma dēļ}zero{Paziņojumu rādīšana ir pārtraukta režīma “{mode}” un vēl # režīmu dēļ}one{Paziņojumu rādīšana ir pārtraukta režīma “{mode}” un vēl # režīma dēļ}other{Paziņojumu rādīšana ir pārtraukta režīma “{mode}” un vēl # režīmu dēļ}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Sākt tūlīt"</string>
@@ -707,6 +709,8 @@
     <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_mode" msgid="6867838048430807128">"zvanītāja režīms"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <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>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrēt"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tastatūrā nospiediet darbību taustiņu."</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Lieliski!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Jūs sekmīgi veicāt visu lietotņu skatīšanas žestu."</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastatūras fona apgaismojums"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Līmenis numur %1$d, kopā ir %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Mājas kontrolierīces"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index f991c1b..783e52e 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Известувањата се паузирани од „Не вознемирувај“"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Нема известувања}=1{Известувањата ги паузираше {mode}}=2{Известувањата ги паузираа {mode} и уште еден режим}one{Известувањата ги паузираа {mode} и уште # режим}other{Известувањата ги паузираа {mode} и уште # режими}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Започни сега"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Следење на главата"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Допрете за да го промените режимот на ѕвончето"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"режим на ѕвонче"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"исклучен звук"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"вклучен звук"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вибрации"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Притиснете го копчето за дејство на тастатурата"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Браво!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Го завршивте движењето за прегледување на сите апликации"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Осветлување на тастатура"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Ниво %1$d од %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Контроли за домот"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 784c896..3134872 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"വിജറ്റ് ഉപയോഗിച്ച് ഒരു ആപ്പ് തുറക്കാൻ, ഇത് നിങ്ങൾ തന്നെയാണെന്ന് പരിശോധിച്ചുറപ്പിക്കേണ്ടതുണ്ട്. നിങ്ങളുടെ ടാബ്‌ലെറ്റ് ലോക്കായിരിക്കുമ്പോഴും എല്ലാവർക്കും അത് കാണാനാകുമെന്നതും ഓർക്കുക. ചില വിജറ്റുകൾ നിങ്ങളുടെ ലോക്ക് സ്‌ക്രീനിന് ഉള്ളതായിരിക്കില്ല, അവ ഇവിടെ ചേർക്കുന്നത് സുരക്ഷിതവുമായിരിക്കില്ല."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"മനസ്സിലായി"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"വിജറ്റുകൾ"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"വിജറ്റുകൾ\" കുറുക്കുവഴി ചേർക്കാൻ, ക്രമീകരണത്തിൽ \"ലോക്ക് സ്‌ക്രീനിൽ വിജറ്റുകൾ കാണിക്കുക\" പ്രവർത്തനക്ഷമമാക്കിയെന്ന് ഉറപ്പാക്കുക."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"ക്രമീകരണം"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ശല്യപ്പെടുത്തരുത്\' വഴി അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തി"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{അറിയിപ്പുകൾ ഒന്നുമില്ല}=1{{mode}, അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തിയിരിക്കുന്നു}=2{{mode} എന്നതും മറ്റൊരു മോഡും, അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തിയിരിക്കുന്നു}other{{mode} എന്നതും മറ്റ് # മോഡുകളും, അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തിയിരിക്കുന്നു}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ഇപ്പോൾ ആരംഭിക്കുക"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ഹെഡ് ട്രാക്കിംഗ്"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"റിംഗർ മോഡ് മാറ്റാൻ ടാപ്പ് ചെയ്യുക"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"റിംഗർ മോഡ്"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"മ്യൂട്ട് ചെയ്യുക"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"അൺമ്യൂട്ട് ചെയ്യുക"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"വൈബ്രേറ്റ് ചെയ്യുക"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"കീബോഡ് കുറുക്കുവഴികൾ"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"കീബോർഡ് കുറുക്കുവഴികൾ ഇഷ്ടാനുസൃതമാക്കുക"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"കുറുക്കുവഴി നീക്കം ചെയ്യണോ?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ഡിഫോൾട്ടിലേക്ക് തിരികെ റീസെറ്റ് ചെയ്യണോ?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"കുറുക്കുവഴി അസൈൻ ചെയ്യാൻ കീ അമർത്തുക"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"ഇത് നിങ്ങളുടെ ഇഷ്‌ടാനുസൃത കുറുക്കുവഴി ശാശ്വതമായി ഇല്ലാതാക്കും."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"നിങ്ങളുടെ എല്ലാ ഇഷ്‍ടാനുസൃത കുറുക്കുവഴികളും ശാശ്വതമായി ഇത് ഇല്ലാതാക്കും."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"തിരയൽ കുറുക്കുവഴികൾ"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"തിരയൽ ഫലങ്ങളൊന്നുമില്ല"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ചുരുക്കൽ ഐക്കൺ"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"കീബോർഡ് ക്രമീകരണം"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"കുറുക്കുവഴി സജ്ജീകരിക്കുക"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"നീക്കം ചെയ്യുക"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"ഉവ്വ്, റീസെറ്റ് ചെയ്യുക"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"റദ്ദാക്കുക"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"കീ അമർത്തുക"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"കീ കോമ്പിനേഷൻ ഇതിനകം ഉപയോഗത്തിലുണ്ട്. മറ്റൊരു കീ പരീക്ഷിക്കുക."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"നിങ്ങളുടെ കീബോർഡിലെ ആക്ഷൻ കീ അമർത്തുക"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"അഭിനന്ദനങ്ങൾ!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"\'എല്ലാ ആപ്പുകളും കാണുക\' ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"കീബോഡ് ബാക്ക്‌ലൈറ്റ്"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-ൽ %1$d-ാമത്തെ ലെവൽ"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ഹോം കൺട്രോളുകൾ"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 6e60b71..42182bf 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Бүү саад бол горимын түр зогсоосон мэдэгдэл"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Мэдэгдэл байхгүй}=1{Мэдэгдлийг {mode} түр зогсоосон}=2{Мэдэгдлийг {mode} болон өөр нэг горим түр зогсоосон}other{Мэдэгдлийг {mode} болон өөр # горим түр зогсоосон}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Одоо эхлүүлэх"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Толгой хянах"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Хонхны горимыг өөрчлөхийн тулд товшино уу"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"хонхны горим"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"дууг хаах"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"дууг нээх"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"чичрэх"</string>
@@ -1443,7 +1447,7 @@
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Болсон"</string>
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Дэлгэх дүрс тэмдэг"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"эсвэл"</string>
-    <string name="shortcut_helper_key_combinations_and_conjunction" msgid="6138186504075880224">"нэмэх нь"</string>
+    <string name="shortcut_helper_key_combinations_and_conjunction" msgid="6138186504075880224">"болон"</string>
     <string name="shortcut_helper_key_combinations_forward_slash" msgid="1238652537199346970">"урагшаа ташуу зураас"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Чирэх бариул"</string>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Гарын тохиргоо"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Гар дээрх тусгай товчлуурыг дарна уу"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Сайн байна!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Та бүх аппыг харах зангааг гүйцэтгэлээ"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Гарын арын гэрэл"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-с %1$d-р түвшин"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Гэрийн удирдлага"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index c21a666..b108ccc 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -113,7 +113,7 @@
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"एक अ‍ॅप रेकॉर्ड करा"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"पूर्ण स्क्रीन रेकॉर्ड करा"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"संपूर्ण स्क्रीन रेकॉर्ड करा: %s"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"तुम्ही तुमची पूर्ण स्क्रीन रेकॉर्ड करता, तेव्हा तुमच्या स्क्रीनवर दाखवलेली कोणतीही गोष्टी रेकॉर्ड केली जाते. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"तुम्ही तुमची पूर्ण स्क्रीन रेकॉर्ड करता, तेव्हा तुमच्या स्क्रीनवर दाखवलेली कोणतीही गोष्ट रेकॉर्ड केली जाते. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"तुम्ही अ‍ॅप रेकॉर्ड करता, तेव्हा त्या अ‍ॅपमध्ये दाखवलेली किंवा प्ले केलेली कोणतीही गोष्ट रेकॉर्ड केली जाते. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"स्क्रीन रेकॉर्ड करा"</string>
     <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"रेकॉर्ड करण्यासाठी अ‍ॅप निवडा"</string>
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"विजेट वापरून अ‍ॅप उघडण्यासाठी, तुम्हाला हे तुम्हीच असल्याची पडताळणी करावी लागेल. तसेच, लक्षात ठेवा, तुमचा टॅबलेट लॉक असतानादेखील कोणीही ती पाहू शकते. काही विजेट कदाचित तुमच्या लॉक स्‍क्रीनसाठी नाहीत आणि ती इथे जोडणे असुरक्षित असू शकते."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"समजले"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"विजेट"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"विजेट\" शॉर्टकट जोडण्यासाठी, सेटिंग्जमध्ये \"लॉक स्‍क्रीनवर विजेट दाखवा\" सुरू असल्याची खात्री करा."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"सेटिंग्ज"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"व्यत्यय आणून नकाद्वारे सूचना थांबवल्या"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{कोणतेही नोटिफिकेशन नाही}=1{{mode} द्वारे नोटिफिकेशन थांबवली आहेत}=2{{mode} द्वारे आणि आणखी एका मोडद्वारे नोटिफिकेशन थांबवली आहेत}other{{mode} द्वारे आणि आणखी # मोडद्वारे नोटिफिकेशन थांबवली आहेत}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"आता सुरू करा"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"हेड ट्रॅकिंग"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"रिंगर मोड बदलण्यासाठी टॅप करा"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"रिंगर मोड"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्यूट करा"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"म्यूट काढून टाका"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"व्हायब्रेट करा"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"कीबोर्ड शॉर्टकट कस्टमाइझ करा"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"शॉर्टकट काढून टाकायचा आहे का?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"डीफॉल्टवर पुन्हा रीसेट करायचे आहे का?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"शॉर्टकट असाइन करण्यासाठी की प्रेस करा"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"यामुळे तुमचा कस्टम शॉर्टकट कायमचा हटवला जाईल."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"हे तुमचे सर्व कस्टम शॉर्टकट कायमचे हटवेल."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"शोधण्यासाठी शॉर्टकट"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"कोणतेही शोध परिणाम नाहीत"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"कोलॅप्स करा आयकन"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"कीबोर्ड सेटिंग्ज"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"शॉर्टकट सेट करा"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"काढून टाका"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"होय, रीसेट करा"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"रद्द करा"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"की प्रेस करा"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"की कॉम्बिनेशन आधीपासून वापरले जात आहे. दुसरी की वापरून पहा."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"तुमच्या कीबोर्डवर अ‍ॅक्शन की प्रेस करा"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"खूप छान!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"तुम्ही ॲप्स पाहण्याचे जेश्चर पूर्ण केले आहे"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"कीबोर्ड बॅकलाइट"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d पैकी %1$d पातळी"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"होम कंट्रोल"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 62f85a5..6b9d6d6 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Untuk membuka apl menggunakan widget, anda perlu mengesahkan identiti anda. Selain itu, perlu diingat bahawa sesiapa sahaja boleh melihat widget tersebut, walaupun semasa tablet anda dikunci. Sesetengah widget mungkin tidak sesuai untuk skrin kunci anda dan mungkin tidak selamat untuk ditambahkan di sini."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widget"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Untuk menambahkan pintasan \"Widget\", pastikan \"Tunjukkan widget pada skrin kunci\" didayakan dalam tetapan."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Tetapan"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Tukar pengguna"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu tarik turun"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua apl dan data dalam sesi ini akan dipadam."</string>
@@ -593,6 +591,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Pemberitahuan"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Perbualan"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Kosongkan semua pemberitahuan senyap"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Pemberitahuan dijeda oleh Jangan Ganggu"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Tiada pemberitahuan}=1{Pemberitahuan dijeda oleh {mode}}=2{Pemberitahuan dijeda oleh {mode} dan satu lagi mod yang lain}other{Pemberitahuan dijeda oleh {mode} dan # mod yang lain}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Mulakan sekarang"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Penjejakan Kepala"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Ketik untuk menukar mod pendering"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"mod pendering"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"redam"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"nyahredam"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"getar"</string>
@@ -1426,20 +1428,17 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Pintasan papan kekunci"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sesuaikan pintasan papan kekunci"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Alih keluar pintasan?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Tetapkan kembali kepada lalai?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Tekan kekunci untuk menetapkan pintasan"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Tindakan ini akan memadamkan pintasan tersuai anda secara kekal."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Tindakan ini akan memadamkan semua pintasan tersuai anda secara kekal."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pintasan carian"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Tiada hasil carian"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Kuncupkan ikon"</string>
     <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikon kekunci tindakan atau Meta"</string>
     <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikon tambah"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Sesuaikan"</string>
-    <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
-    <skip />
+    <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Tetapkan semula"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Selesai"</string>
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Kembangkan ikon"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"atau"</string>
@@ -1449,8 +1448,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tetapan Papan Kekunci"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Tetapkan pintasan"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Alih keluar"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Ya, tetapkan semula"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Batal"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tekan kekunci"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Gabungan kekunci sudah digunakan. Cuba kekunci lain."</string>
@@ -1482,6 +1480,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tekan kekunci tindakan pada papan kekunci anda"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Syabas!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Anda telah melengkapkan gerak isyarat lihat semua apl"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Cahaya latar papan kekunci"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Tahap %1$d daripada %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Kawalan Rumah"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 393f2f2..50f75ee 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"အကြောင်းကြားချက်များကို \'မနှောင့်ယှက်ရ\' က ခေတ္တရပ်ထားသည်"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{အကြောင်းကြားချက် မရှိပါ}=1{{mode} က ခဏရပ်ထားသော အကြောင်းကြားချက်များ}=2{{mode} နှင့် အခြားမုဒ်တစ်ခုက ခဏရပ်ထားသော အကြောင်းကြားချက်များ}other{{mode} နှင့် အခြားမုဒ် # ခုက ခဏရပ်ထားသော အကြောင်းကြားချက်များ}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ယခု စတင်ပါ"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ခေါင်းလှုပ်ရှားမှု"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"ဖုန်းခေါ်သံမုဒ်သို့ ပြောင်းရန် တို့ပါ"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"အသံမြည်မုဒ်"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"အသံပိတ်ရန်"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"အသံဖွင့်ရန်"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"တုန်ခါမှု"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ကီးဘုတ်တွင် လုပ်ဆောင်ချက်ကီး နှိပ်ပါ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"အလွန်ကောင်းပါသည်။"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"အက်ပ်အားလုံးကို ကြည့်ခြင်းလက်ဟန် သင်ခန်းစာပြီးပါပြီ"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ကီးဘုတ်နောက်မီး"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"အဆင့် %2$d အနက် %1$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"အိမ်ထိန်းချုပ်မှုများ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 7454d63..f84353f 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Varsler"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Samtaler"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Fjern alle lydløse varsler"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Varsler er satt på pause av «Ikke forstyrr»"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Ingen varsler}=1{Varsler er satt på pause av {mode}}=2{Varsler er satt på pause av {mode} og én modus til}other{Varsler er satt på pause av {mode} og # moduser til}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start nå"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Hodesporing"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Trykk for å endre ringemodus"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"modus for ringeprogrammet"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"kutt lyden"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå på lyden"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrer"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Trykk på handlingstasten på tastaturet"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bra!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Du har fullført bevegelsen for å se alle apper"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Bakgrunnslys for tastatur"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivå %1$d av %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Hjemkontroller"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 9b8af93..8fd8367 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"बाधा नपुऱ्याउनुहोस् नामक मोडमार्फत पज पारिएका सूचनाहरू"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{कुनै पनि नोटिफिकेसन छैन}=1{{mode} ले गर्दा नोटिफिकेसनहरू पज गरिएका छन्}=2{{mode} र अन्य एक मोडले गर्दा नोटिफिकेसनहरू पज गरिएका छन्}other{{mode} र अन्य # वटा मोडले गर्दा नोटिफिकेसनहरू पज गरिएका छन्}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"अहिले न"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"हेड ट्र्याकिङ"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"रिङ्गर मोड बदल्न ट्याप गर्नुहोस्"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"घण्टी बजाउने मोड"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्युट गर्नुहोस्"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"अनम्युट गर्नुहोस्"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"कम्पन गर्नुहोस्"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"आफ्नो किबोर्डमा भएको एक्सन की थिच्नुहोस्"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"स्याबास!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"तपाईंले जेस्चर प्रयोग गरी सबै एपहरू हेर्ने तरिका सिक्नुभएको छ"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"किबोर्ड ब्याकलाइट"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d मध्ये %1$d औँ स्तर"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"होम कन्ट्रोलहरू"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 12f4156..d03b5fb 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Als je een app wilt openen met een widget, moet je verifiëren dat jij het bent. Houd er ook rekening mee dat iedereen ze kan bekijken, ook als je tablet vergrendeld is. Bepaalde widgets zijn misschien niet bedoeld voor je vergrendelscherm en kunnen hier niet veilig worden toegevoegd."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widgets"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Als je de snelkoppeling Widgets wilt toevoegen, zorg je dat Widgets tonen op het vergrendelingsscherm aanstaat in de instellingen."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Instellingen"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Gebruiker wijzigen"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pull-downmenu"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps en gegevens in deze sessie worden verwijderd."</string>
@@ -593,6 +591,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Meldingen"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Gesprekken"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Alle stille meldingen wissen"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Meldingen onderbroken door \'Niet storen\'"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Geen meldingen}=1{Meldingen onderbroken door {mode}}=2{Meldingen onderbroken door {mode} en 1 andere modus}other{Meldingen onderbroken door {mode} en # andere modi}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Nu starten"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Hoofdtracking"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Tik om de beltoonmodus te wijzigen"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"beltoonmodus"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"geluid uit"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"geluid aanzetten"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"trillen"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Sneltoetsen"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sneltoetsen aanpassen"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Sneltoets verwijderen?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Resetten naar standaard?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Druk op de toets om de sneltoets toe te wijzen"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Hiermee wordt je aangepaste sneltoets definitief verwijderd."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Hiermee worden al je aangepaste snelkoppelingen definitief verwijderd."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sneltoetsen zoeken"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Geen zoekresultaten"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icoon voor samenvouwen"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Toetsenbordinstellingen"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Sneltoets instellen"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Verwijderen"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Ja, resetten"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annuleren"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Druk op een toets"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Toetsencombinatie is al in gebruik. Probeer een andere toets."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Druk op de actietoets op het toetsenbord"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Goed gedaan!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Je weet nu hoe je het gebaar Alle apps bekijken maakt"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Achtergrondverlichting van toetsenbord"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d van %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Bediening voor in huis"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 28d8cfc..91900e7 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ବିକଳ୍ପ ଦ୍ୱାରା ବିଜ୍ଞପ୍ତି ପଜ୍‍ ହୋଇଛି"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ}=1{{mode} ଦ୍ୱାରା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ବିରତ କରାଯାଇଛି}=2{{mode} ଏବଂ ଅନ୍ୟ ଏକ ମୋଡ ଦ୍ୱାରା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ବିରତ କରାଯାଇଛି}other{{mode} ଏବଂ ଅନ୍ୟ # ମୋଡ ଦ୍ୱାରା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ବିରତ କରାଯାଇଛି}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ବର୍ତ୍ତମାନ ଆରମ୍ଭ କରନ୍ତୁ"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ହେଡ ଟ୍ରାକିଂ"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"ରିଙ୍ଗର୍ ମୋଡ୍ ବଦଳାଇବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"ରିଂଗର ମୋଡ"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ମ୍ୟୁଟ"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ଅନ୍‍-ମ୍ୟୁଟ୍ କରନ୍ତୁ"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ଭାଇବ୍ରେଟ୍"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ଆପଣଙ୍କର କୀବୋର୍ଡରେ ଆକ୍ସନ କୀ\'କୁ ଦବାନ୍ତୁ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ବହୁତ ବଢ଼ିଆ!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ଆପଣ ସମସ୍ତ ଆପ୍ସ ଜେଶ୍ଚରକୁ ଭ୍ୟୁ କରିବା ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"କୀବୋର୍ଡ ବେକଲାଇଟ"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dରୁ %1$d ନମ୍ବର ଲେଭେଲ"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ହୋମ କଣ୍ଟ୍ରୋଲ୍ସ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 9df55d6..ba51bf2 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਰੋਕਿਆ ਗਿਆ"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{ਕੋਈ ਸੂਚਨਾ ਨਹੀਂ ਹੈ}=1{{mode} ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ}=2{{mode} ਅਤੇ ਇੱਕ ਹੋਰ ਮੋਡ ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ}other{{mode} ਅਤੇ # ਹੋਰ ਮੋਡਾਂ ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ਹੁਣੇ ਸ਼ੁਰੂ ਕਰੋ"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ਹੈੱਡ ਟਰੈਕਿੰਗ"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"ਰਿੰਗਰ ਮੋਡ ਨੂੰ ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"ਰਿੰਗਰ ਮੋਡ"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ਮਿਊਟ ਕਰੋ"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ਅਣਮਿਊਟ ਕਰੋ"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ਥਰਥਰਾਹਟ"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ਆਪਣੇ ਕੀ-ਬੋਰਡ \'ਤੇ ਕਾਰਵਾਈ ਕੁੰਜੀ ਨੂੰ ਦਬਾਓ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ਬਹੁਤ ਵਧੀਆ!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ਤੁਸੀਂ \'ਸਾਰੀਆਂ ਐਪਾਂ ਦੇਖੋ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ ਹੈ"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ਕੀ-ਬੋਰਡ ਬੈਕਲਾਈਟ"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ਵਿੱਚੋਂ %1$d ਪੱਧਰ"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ਹੋਮ ਕੰਟਰੋਲ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 9edb183e..6785668 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Aby otworzyć aplikację za pomocą widżetu, musisz potwierdzić swoją tożsamość. Pamiętaj też, że każdy będzie mógł wyświetlić widżety nawet wtedy, gdy tablet będzie zablokowany. Niektóre widżety mogą nie być przeznaczone do umieszczenia na ekranie blokady i ich dodanie w tym miejscu może być niebezpieczne."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widżety"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Aby dodać skrót „Widżety”, upewnij się, że opcja „Pokaż widżety na ekranie blokady” jest włączona w ustawieniach."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Ustawienia"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Przełącz użytkownika"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wszystkie aplikacje i dane w tej sesji zostaną usunięte."</string>
@@ -593,6 +591,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Powiadomienia"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Rozmowy"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Usuń wszystkie ciche powiadomienia"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Powiadomienia wstrzymane przez tryb Nie przeszkadzać"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Brak powiadomień}=1{Powiadomienia są wstrzymane przez tryb {mode}}=2{Powiadomienia są wstrzymane przez tryb {mode} i 1 inny tryb}few{Powiadomienia są wstrzymane przez tryb {mode} i # inne tryby}many{Powiadomienia są wstrzymane przez tryb {mode} i # innych trybów}other{Powiadomienia są wstrzymane przez tryb {mode} i # innego trybu}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Rozpocznij teraz"</string>
@@ -707,6 +707,8 @@
     <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_mode" msgid="6867838048430807128">"tryb dzwonka"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"wycisz"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"wyłącz wyciszenie"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"włącz wibracje"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Skróty klawiszowe"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Dostosuj skróty klawiszowe"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Usunąć skrót?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Zresetować do ustawień domyślnych?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Naciśnij klawisz, aby przypisać skrót"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Spowoduje to trwałe usunięcie skrótu niestandardowego."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Spowoduje to trwałe usunięcie wszystkich skrótów niestandardowych."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Skróty do wyszukiwania"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Brak wyników wyszukiwania"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zwijania"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Ustawienia klawiatury"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ustaw skrót"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Usuń"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Tak, zresetuj"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Anuluj"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Naciśnij klawisz"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinacja klawiszy jest już używana. Użyj innego klawisza."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Naciśnij klawisz działania na klawiaturze"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Brawo!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Znasz już gest wyświetlania wszystkich aplikacji"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podświetlenie klawiatury"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Poziom %1$d z %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Sterowanie domem"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 3871f7a..9515227 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -306,7 +306,7 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Usar Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Conectado"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Compartilhamento de áudio"</string>
-    <string name="quick_settings_bluetooth_device_audio_sharing_or_switch_active" msgid="8680997711431098238">"Compatível com compartilhamento de áudio"</string>
+    <string name="quick_settings_bluetooth_device_audio_sharing_or_switch_active" msgid="8680997711431098238">"Aceita compartilhamento de áudio"</string>
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvo"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ativar"</string>
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificações"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Apagar todas as notificações silenciosas"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificações pausadas pelo modo \"Não perturbe\""</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Sem notificações}=1{Notificações pausadas pelo modo {mode}}=2{Notificações pausadas por {mode} e mais um modo}one{Notificações pausadas por {mode} e mais # modo}many{Notificações pausadas por {mode} e mais # de modos}other{Notificações pausadas por {mode} e mais # modos}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Rastreamento de cabeça"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Toque para mudar o modo da campainha"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"modo da campainha"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar o som"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ativar o som"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1438,8 +1442,7 @@
     <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ícone da tecla de ação"</string>
     <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ícone de adição"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
-    <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
-    <skip />
+    <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Redefinir"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Concluir"</string>
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone \"Abrir\""</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
@@ -1482,6 +1485,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pressione a tecla de ação no teclado"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Muito bem!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Você concluiu o gesto para ver todos os apps"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz de fundo do teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Automação residencial"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index c0e65c7..40df4c0 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir uma app através de um widget, vai ter de validar a sua identidade. Além disso, tenha em atenção que qualquer pessoa pode ver os widgets, mesmo quando o tablet estiver bloqueado. Alguns widgets podem não se destinar ao ecrã de bloqueio e pode ser inseguro adicioná-los aqui."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widgets"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Para adicionar o atalho \"Widgets\", certifique-se de que a opção \"Mostrar widgets no ecrã de bloqueio\" está ativada nas definições."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Definições"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mudar utilizador"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu pendente"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todas as apps e dados desta sessão serão eliminados."</string>
@@ -593,6 +591,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificações"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Limpar todas as notificações silenciosas"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificações colocadas em pausa pelo modo Não incomodar."</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Sem notificações}=1{Notificações pausadas pelo modo {mode}}=2{Notificações pausadas pelo modo {mode} e mais um modo}many{Notificações pausadas pelo modo {mode} e mais # modos}other{Notificações pausadas pelo modo {mode} e mais # modos}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Começar agora"</string>
@@ -707,6 +707,7 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Posição da cabeça"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Toque para alterar o modo de campainha"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"modo de som"</string>
+    <string name="volume_ringer_drawer_closed_content_description" msgid="4737792429808781745">"<xliff:g id="VOLUME_RINGER_STATUS">%1$s</xliff:g>, toque para alterar o modo de som"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar som"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"reativar som"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1426,20 +1427,17 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos de teclado"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalize os atalhos de teclado"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Remover atalho?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Repor para a predefinição?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Prima a tecla para atribuir o atalho"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Esta ação elimina o atalho personalizado permanentemente."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Esta ação elimina todos os seus atalhos personalizados permanentemente."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pesquisar atalhos"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado da pesquisa"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone de reduzir"</string>
     <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ícone da tecla Meta ou de ação"</string>
     <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ícone de mais"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
-    <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
-    <skip />
+    <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Repor"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Concluir"</string>
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone de expandir"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
@@ -1449,8 +1447,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Definições do teclado"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Configurar atalho"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Remover"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Sim, repor"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Prima a tecla"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"A combinação de teclas já está a ser usada. Experimente outra tecla."</string>
@@ -1482,6 +1479,7 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Prima a tecla de ação no teclado"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Muito bem!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Concluiu o gesto para ver todas as apps"</string>
+    <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animação do tutorial, clique para pausar e retomar a reprodução."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz do teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Controlos domésticos"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 3871f7a..9515227 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -306,7 +306,7 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Usar Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Conectado"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Compartilhamento de áudio"</string>
-    <string name="quick_settings_bluetooth_device_audio_sharing_or_switch_active" msgid="8680997711431098238">"Compatível com compartilhamento de áudio"</string>
+    <string name="quick_settings_bluetooth_device_audio_sharing_or_switch_active" msgid="8680997711431098238">"Aceita compartilhamento de áudio"</string>
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvo"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ativar"</string>
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificações"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Apagar todas as notificações silenciosas"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificações pausadas pelo modo \"Não perturbe\""</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Sem notificações}=1{Notificações pausadas pelo modo {mode}}=2{Notificações pausadas por {mode} e mais um modo}one{Notificações pausadas por {mode} e mais # modo}many{Notificações pausadas por {mode} e mais # de modos}other{Notificações pausadas por {mode} e mais # modos}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Rastreamento de cabeça"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Toque para mudar o modo da campainha"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"modo da campainha"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar o som"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ativar o som"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1438,8 +1442,7 @@
     <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ícone da tecla de ação"</string>
     <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ícone de adição"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
-    <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
-    <skip />
+    <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Redefinir"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Concluir"</string>
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone \"Abrir\""</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
@@ -1482,6 +1485,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pressione a tecla de ação no teclado"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Muito bem!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Você concluiu o gesto para ver todos os apps"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz de fundo do teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Automação residencial"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 5911c40..3b5cd89 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificări"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversații"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Șterge toate notificările silențioase"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificări întrerupte prin „Nu deranja”"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Nicio notificare}=1{Notificările au fost întrerupte de {mode}}=2{Notificările au fost întrerupte de {mode} și de un alt mod}few{Notificările au fost întrerupte de {mode} și de alte # moduri}other{Notificările au fost întrerupte de {mode} și de alte # de moduri}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Începe acum"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Urmărirea mișcărilor capului"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Atinge pentru a schimba modul soneriei"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"modul sonerie"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"dezactivează sunetul"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"activează sunetul"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrații"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Apasă tasta de acțiuni de pe tastatură"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Felicitări!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Ai finalizat gestul pentru afișarea tuturor aplicațiilor"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Iluminarea din spate a tastaturii"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivelul %1$d din %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Comenzi pentru locuință"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 95c4ee3..b026787 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Чтобы открыть приложение, используя виджет, вам нужно будет подтвердить свою личность. Обратите внимание, что виджеты видны всем, даже если планшет заблокирован. Некоторые виджеты не предназначены для использования на заблокированном экране. Добавлять их туда может быть небезопасно."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ОК"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Виджеты"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Чтобы создать ярлык \"Виджеты\", убедитесь, что в настройках включена функция \"Показывать виджеты на заблокированном экране\"."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Настройки"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"В режиме \"Не беспокоить\" уведомления заблокированы"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Уведомлений нет}=1{Режим \"{mode}\" приостанавливает уведомления}=2{Режим \"{mode}\" и ещё один режим приостанавливают уведомления}one{Режим \"{mode}\" и ещё # режим приостанавливают уведомления}few{Режим \"{mode}\" и ещё # режима приостанавливают уведомления}many{Режим \"{mode}\" и ещё # режимов приостанавливают уведомления}other{Режим \"{mode}\" и ещё # режима приостанавливают уведомления}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Начать"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Динамичное"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Нажмите, чтобы изменить режим звонка."</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"режим звонка"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"отключить звук"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"включить звук"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"включить вибрацию"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Быстрые клавиши"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Как настроить быстрые клавиши"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Удалить сочетание клавиш?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Сбросить настройки?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Нажмите клавишу, чтобы назначить сочетание клавиш."</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Настроенное сочетание будет безвозвратно удалено."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Все пользовательские ярлыки будут безвозвратно удалены."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Найти быстрые клавиши"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ничего не найдено"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок \"Свернуть\""</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Настройки клавиатуры"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Задать сочетание клавиш"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Удалить"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Сбросить"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Отмена"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Нажмите клавишу"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Это сочетание клавиш уже используется. Попробуйте другое."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Нажмите клавишу действия на клавиатуре."</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Блестяще!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Вы выполнили жест для просмотра всех приложений."</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Подсветка клавиатуры"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Уровень %1$d из %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Управление домом"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 36879d6..a496c7c 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"බාධා නොකරන්න මගින් විරාම කරන ලද දැනුම්දීම්"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{දැනුම්දීම් නැත}=1{{mode} මගින් දැනුම්දීම් විරාම කරන ලදි}=2{{mode} සහ තව එක ප්‍රකාරයක් මගින් දැනුම්දීම් විරාම කරන ලදි}one{{mode} සහ තව ප්‍රකාර #ක් මගින් දැනුම්දීම් විරාම කරන ලදි}other{{mode} සහ තව ප්‍රකාර #ක් මගින් දැනුම්දීම් විරාම කරන ලදි}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"දැන් අරඹන්න"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"හිස ලුහුබැඳීම"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"නාදකය වෙනස් කිරීමට තට්ටු කරන්න"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"හඬ නඟන ආකාරය"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"නිහඬ කරන්න"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"නිශ්ශබ්දතාවය ඉවත් කරන්න"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"කම්පනය"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ඔබේ යතුරු පුවරුවේ ක්‍රියාකාරී යතුර ඔබන්න"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"හොඳින් කළා!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ඔබ සියලු යෙදුම් ඉංගිත බැලීම සම්පූර්ණ කර ඇත"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"යතුරු පුවරු පසු ආලෝකය"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dන් %1$d වැනි මට්ටම"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"නිවෙස් පාලන"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index c972c18..0c4880d 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ak chcete otvoriť aplikáciu pomocou miniaplikácie, budete musieť overiť svoju totožnosť. Pamätajte, že si miniaplikáciu môže pozrieť ktokoľvek, aj keď máte tablet uzamknutý. Niektoré miniaplikácie možno nie sú určené pre uzamknutú obrazovku a ich pridanie tu môže byť nebezpečné."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Dobre"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Miniaplikácie"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Ak chcete pridať odkaz Miniaplikácie, uistite sa, že v nastaveniach je zapnutá možnosť Zobrazovať miniaplikácie na uzamknutej obrazovke."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Nastavenia"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Prepnutie používateľa"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rozbaľovacia ponuka"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Všetky aplikácie a údaje v tejto relácii budú odstránené."</string>
@@ -593,6 +591,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Upozornenia"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzácie"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Vymazať všetky tiché upozornenia"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Upozornenia sú pozastavené režimom bez vyrušení"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Žiadne upozornenia}=1{Upozornenia boli pozastavené režimom {mode}}=2{Upozornenia boli pozastavené režimom {mode} a jedným ďalším}few{Upozornenia boli pozastavené režimom {mode} a # ďalšími}many{Notifications paused by {mode} and # other modes}other{Upozornenia boli pozastavené režimom {mode} a # ďalšími}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Spustiť"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Sledovanie hlavy"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Režim zvonenia zmeníte klepnutím"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"režim zvonenia"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vypnite zvuk"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"zapnite zvuk"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"zapnite vibrovanie"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Klávesové skratky"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prispôsobenie klávesových skratiek"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Chcete skratku odstrániť?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Chcete resetovať na predvolené nastavenie?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Stlačením klávesa priraďte skratku"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Týmto natrvalo odstránite vlastnú skratku."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Týmto natrvalo odstránite všetky vlastné odkazy."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prehľadávať skratky"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Žiadne výsledky vyhľadávania"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zbalenia"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Nastavenia klávesnice"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nastaviť skratku"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Odstrániť"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Áno, resetovať"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Zrušiť"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Stlačte kláves"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinácia klávesov sa už používa. Skúste iný kláves."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Stlačte na klávesnici akčný kláves"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Dobre!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Použili ste gesto na zobrazenie všetkých aplikácií."</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podsvietenie klávesnice"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. úroveň z %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Ovládanie domácnosti"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 914df72..dbeed9d 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Če želite aplikacijo odpreti s pripomočkom, morate potrditi, da ste to vi. Upoštevajte tudi, da si jih lahko ogledajo vsi, tudi ko je tablični računalnik zaklenjen. Nekateri pripomočki morda niso predvideni za uporabo na zaklenjenem zaslonu, zato jih tukaj morda ni varno dodati."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Razumem"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Pripomočki"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Če želite dodati bližnjico »Pripomočki«, v nastavitvah omogočite možnost »Prikaz pripomočkov na zaklenjenem zaslonu«."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Nastavitve"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Preklop med uporabniki"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"spustni meni"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Vse aplikacije in podatki v tej seji bodo izbrisani."</string>
@@ -593,6 +591,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Obvestila"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Pogovori"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Brisanje vseh tihih obvestil"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Prikazovanje obvestil je začasno zaustavljeno z načinom »ne moti«"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Ni obvestil}=1{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode}}=2{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode} in še enim drugim načinom}one{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode} in še # drugim načinom}two{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode} in še # drugima načinoma}few{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode} in še # drugimi načini}other{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode} in še # drugimi načini}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Začni zdaj"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Spremljanje glave"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Dotaknite se, če želite spremeniti način zvonjenja."</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"način zvonjenja"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"izklop zvoka"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"vklop zvoka"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibriranje"</string>
@@ -1426,20 +1428,17 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Bližnjične tipke"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagajanje bližnjičnih tipk"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Želite odstraniti bližnjico?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Želite ponastaviti na privzete bližnjice?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pritisnite tipko za dodelitev bližnjice"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"S tem boste trajno izbrisali bližnjico po meri."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"S tem boste trajno izbrisali vse bližnjice po meri."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Iskanje po bližnjicah"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ni rezultatov iskanja"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za strnitev"</string>
     <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona tipke za dejanje ali metapodatke"</string>
     <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona znaka plus"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prilagodi"</string>
-    <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
-    <skip />
+    <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Ponastavi"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Končano"</string>
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za razširitev"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ali"</string>
@@ -1449,8 +1448,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Nastavitve tipkovnice"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nastavite bližnjico"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Odstrani"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Da, ponastavi"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Prekliči"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite tipko"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinacija tipk je že v uporabi. Poskusite z drugo tipko."</string>
@@ -1482,6 +1480,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pritisnite tipko za dejanja na tipkovnici"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Odlično!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Izvedli ste potezo za ogled vseh aplikacij"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Osvetlitev tipkovnice"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Stopnja %1$d od %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrolniki za dom"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 6a597f7..743aad0 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Njoftimet"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Bisedat"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Pastro të gjitha njoftimet në heshtje"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Njoftimet janë vendosur në pauzë nga modaliteti \"Mos shqetëso\""</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Asnjë njoftim}=1{Njoftimet u vendosën në pauzë nga {mode}}=2{Njoftimet u vendosën në pauzë nga {mode} dhe një modalitet tjetër}other{Njoftimet u vendosën në pauzë nga {mode} dhe # modalitete të tjera}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Fillo tani"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Ndjekja e lëvizjeve të kokës"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Trokit për të ndryshuar modalitetin e ziles"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"modaliteti i ziles"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"çaktivizo audion"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktivizo audion"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"lësho dridhje"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Shtyp tastin e veprimit në tastierë"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Shumë mirë!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Përfundove gjestin për shikimin e të gjitha aplikacioneve"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Drita e sfondit e tastierës"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveli: %1$d nga %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrollet e shtëpisë"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 560f4d7..9a15268 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Да бисте отворили апликацију која користи виџет, треба да потврдите да сте то ви. Имајте у виду да свако може да га види, чак и када је таблет закључан. Неки виџети можда нису намењени за закључани екран и можда није безбедно да их тамо додате."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Важи"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Виџети"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Да бисте додали пречицу Виџети, уверите се да је у подешавањима омогућено Приказуј виџете на закључаном екрану."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Подешавања"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Обавештења су паузирана режимом Не узнемиравај"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Нема обавештења}=1{Обавештења је паузирао {mode}}=2{Обавештења су паузирали {mode} и још један режим}one{Обавештења су паузирали {mode} и још # режим}few{Обавештења су паузирали {mode} и још # режима}other{Обавештења су паузирали {mode} и још # режима}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Започни"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Праћење главе"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Додирните да бисте променили режим звона"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"режим звона"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"искључите звук"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"укључите звук"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вибрација"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Тастерске пречице"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Прилагодите тастерске пречице"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Желите да уклоните пречицу?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Желите да ресетујете на подразумевано?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Притисните тастер да бисте доделили пречицу"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Овим ћете трајно избрисати прилагођену пречицу."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Тиме ћете трајно избрисати све прилагођене пречице."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Претражите пречице"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нема резултата претраге"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за скупљање"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Подешавања тастатуре"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Подеси пречицу"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Уклони"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Да, ресетуј"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Откажи"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Притисните тастер"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Комбинација тастера се већ користи. Пробајте са другим тастером."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Притисните тастер радњи на тастатури"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Одлично!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Довршили сте покрет за приказивање свих апликација."</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Позадинско осветљење тастатуре"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. ниво од %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Контроле за дом"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 2996033..c8fee61 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Aviseringar"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Konversationer"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Rensa alla ljudlösa aviseringar"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Aviseringar har pausats via Stör ej"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Inga aviseringar}=1{Aviseringar har pausats av {mode}}=2{Aviseringar har pausats av {mode} och ett annat läge}other{Aviseringar har pausats av {mode} och # andra lägen}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Starta nu"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Huvudspårning"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Tryck för att ändra ringsignalens läge"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"ringsignalläge"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"stänga av ljudet"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå på ljudet"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibration"</string>
@@ -1438,8 +1442,7 @@
     <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikon för åtgärdstangent"</string>
     <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plusikon"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Anpassa"</string>
-    <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
-    <skip />
+    <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Återställ"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Klar"</string>
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikonen Utöka"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
@@ -1482,6 +1485,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tryck på åtgärdstangenten på tangentbordet"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bra gjort!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Du är klar med rörelsen för att se alla apparna."</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Bakgrundsbelysning för tangentbord"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivå %1$d av %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Hemstyrning"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 7084bbf..44bac92 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Arifa"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Mazungumzo"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Futa arifa zote zisizo na sauti"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Kipengele cha Usinisumbue kimesitisha arifa"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Hakuna arifa}=1{Arifa zimesitishwa na {mode}}=2{Arifa zimesitishwa na {mode} na hali nyingine moja}other{Arifa zimesitishwa na {mode} na hali nyingine #}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Anza sasa"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Ufuatilizi wa Kichwa"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Gusa ili ubadilishe hali ya programu inayotoa milio ya simu"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"hali ya programu inayotoa milio ya simu"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"zima sauti"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"washa sauti"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"tetema"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Bonyeza kitufe cha vitendo kwenye kibodi yako"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Vizuri sana!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Umekamilisha mafunzo ya mguso wa kuangalia programu zote"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Mwanga chini ya kibodi"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Kiwango cha %1$d kati ya %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Dhibiti Vifaa Nyumbani"</string>
diff --git a/packages/SystemUI/res/values-sw600dp-land/styles.xml b/packages/SystemUI/res/values-sw600dp-land/styles.xml
index cde1a1373..45698f7 100644
--- a/packages/SystemUI/res/values-sw600dp-land/styles.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/styles.xml
@@ -22,20 +22,20 @@
         <item name="android:layout_marginTop">16dp</item>
         <item name="android:textSize">36sp</item>
         <item name="android:focusable">true</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.AuthNonBioCredential.Subtitle">
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:layout_marginTop">16dp</item>
         <item name="android:textSize">18sp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.AuthNonBioCredential.Description">
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:layout_marginTop">16dp</item>
         <item name="android:textSize">18sp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp-port/styles.xml b/packages/SystemUI/res/values-sw600dp-port/styles.xml
index 85e7af6..8b3e6fd 100644
--- a/packages/SystemUI/res/values-sw600dp-port/styles.xml
+++ b/packages/SystemUI/res/values-sw600dp-port/styles.xml
@@ -30,7 +30,7 @@
         <item name="android:layout_marginTop">24dp</item>
         <item name="android:textSize">36sp</item>
         <item name="android:focusable">true</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
 </resources>
diff --git a/packages/SystemUI/res/values-sw720dp-land/styles.xml b/packages/SystemUI/res/values-sw720dp-land/styles.xml
index e75173d..451a9a9 100644
--- a/packages/SystemUI/res/values-sw720dp-land/styles.xml
+++ b/packages/SystemUI/res/values-sw720dp-land/styles.xml
@@ -22,21 +22,21 @@
         <item name="android:layout_marginTop">16dp</item>
         <item name="android:textSize">36sp</item>
         <item name="android:focusable">true</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.AuthNonBioCredential.Subtitle">
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:layout_marginTop">16dp</item>
         <item name="android:textSize">18sp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.AuthNonBioCredential.Description">
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:layout_marginTop">16dp</item>
         <item name="android:textSize">18sp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
 </resources>
diff --git a/packages/SystemUI/res/values-sw720dp-port/styles.xml b/packages/SystemUI/res/values-sw720dp-port/styles.xml
index 85e7af6..8b3e6fd 100644
--- a/packages/SystemUI/res/values-sw720dp-port/styles.xml
+++ b/packages/SystemUI/res/values-sw720dp-port/styles.xml
@@ -30,7 +30,7 @@
         <item name="android:layout_marginTop">24dp</item>
         <item name="android:textSize">36sp</item>
         <item name="android:focusable">true</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 959e2e6..4c65095 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'தொந்தரவு செய்ய வேண்டாம்\' அம்சத்தின் மூலம் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{அறிவிப்புகள் இல்லை}=1{{mode} பயன்முறையால் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன}=2{{mode} மற்றும் வேறொரு பயன்முறையால் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன}other{{mode} மற்றும் வேறு # பயன்முறைகளால் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"இப்போது தொடங்கு"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ஹெட் டிராக்கிங்"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"ரிங்கர் பயன்முறையை மாற்ற தட்டவும்"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"ரிங்கர் பயன்முறை"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ஒலியடக்கும்"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ஒலி இயக்கும்"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"அதிர்வுறும்"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"உங்கள் கீபோர்டில் ஆக்‌ஷன் பட்டனை அழுத்தவும்"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"அருமை!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"அனைத்து ஆப்ஸையும் பார்ப்பதற்கான சைகை பயிற்சியை நிறைவுசெய்துவிட்டீர்கள்"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"கீபோர்டு பேக்லைட்"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"நிலை, %2$d இல் %1$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ஹோம் கன்ட்ரோல்கள்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index a66821b..ebed1877 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"విడ్జెట్‌ను ఉపయోగించి యాప్‌ను తెరవడానికి, ఇది మీరేనని వెరిఫై చేయాల్సి ఉంటుంది. అలాగే, మీ టాబ్లెట్ లాక్ చేసి ఉన్నప్పటికీ, ఎవరైనా వాటిని చూడగలరని గుర్తుంచుకోండి. కొన్ని విడ్జెట్‌లు మీ లాక్ స్క్రీన్‌కు తగినవి కాకపోవచ్చు, వాటిని ఇక్కడ జోడించడం సురక్షితం కాకపోవచ్చు."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"అర్థమైంది"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"విడ్జెట్‌లు"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"విడ్జెట్‌ల\" షార్ట్‌కట్‌ను జోడించడానికి, సెట్టింగ్‌లలో \"లాక్ స్క్రీన్‌లో విడ్జెట్‌లను చూపండి\" అనే ఆప్షన్‌ను ఎనేబుల్ చేసినట్లు నిర్ధారించుకోండి."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"సెట్టింగ్‌లు"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"అంతరాయం కలిగించవద్దు ద్వారా నోటిఫికేషన్‌లు పాజ్ చేయబడ్డాయి"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{నోటిఫికేషన్‌లు ఏవీ లేవు}=1{{mode} ద్వారా నోటిఫికేషన్‌లు పాజ్ చేయబడ్డాయి}=2{నోటిఫికేషన్‌లు, {mode}, మరో ఒక మోడ్ ద్వారా పాజ్ చేయబడ్డాయి}other{నోటిఫికేషన్‌లు, {mode}, మరో # మోడ్‌ల ద్వారా పాజ్ చేయబడ్డాయి}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ఇప్పుడే ప్రారంభించండి"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"హెడ్ ట్రాకింగ్"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"రింగర్ మోడ్‌ను మార్చడానికి ట్యాప్ చేయండి"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"రింగర్ మోడ్"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"మ్యూట్ చేయి"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"అన్‌మ్యూట్ చేయి"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"వైబ్రేట్"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"కీబోర్డ్ షార్ట్‌కట్‌లు"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"కీబోర్డ్ షార్ట్‌కట్‌లను అనుకూలంగా మార్చండి"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"షార్ట్‌కట్‌ను తీసివేయాలా?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"తిరిగి ఆటోమేటిక్ సెట్టింగ్‌కు రీసెట్ చేయాలా?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"షార్ట్‌కట్‌ను కేటాయించడానికి కీని నొక్కండి"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"ఇది మీ అనుకూల షార్ట్‌కట్‌ను శాశ్వతంగా తొలగిస్తుంది."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"ఇది మీ అనుకూల షార్ట్‌కట్‌లన్నింటిని శాశ్వతంగా తొలగిస్తుంది."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"షార్ట్‌కట్‌లను వెతకండి"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"సెర్చ్ ఫలితాలు ఏవీ లేవు"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"కుదించండి చిహ్నం"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"కీబోర్డ్ సెట్టింగ్‌లు"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"షార్ట్‌కట్‌ను సెట్ చేయండి"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"తీసివేయండి"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"అవును, రీసెట్ చేయాలి"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"రద్దు చేయండి"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"కీని నొక్కండి"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"కీ కాంబినేషన్ ఇప్పటికే వినియోగంలో ఉంది. వేరొక కీని ట్రై చేయండి."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"మీ కీబోర్డ్‌లో యాక్షన్ కీని నొక్కండి"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"చక్కగా చేశారు!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"అన్ని యాప్‌లను చూడడానికి ఉపయోగించే సంజ్ఞకు సంబంధించిన ట్యుటోరియల్‌ను మీరు పూర్తి చేశారు"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"కీబోర్డ్ బ్యాక్‌లైట్"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dలో %1$dవ స్థాయి"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"హోమ్ కంట్రోల్స్"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 5ead29f..fe13888 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"หากต้องการเปิดแอปโดยใช้วิดเจ็ต คุณจะต้องยืนยันตัวตนของคุณ นอกจากนี้ โปรดทราบว่าผู้อื่นจะดูวิดเจ็ตเหล่านี้ได้แม้ว่าแท็บเล็ตจะล็อกอยู่ก็ตาม วิดเจ็ตบางอย่างอาจไม่ได้มีไว้สำหรับหน้าจอล็อกของคุณ และอาจไม่ปลอดภัยที่จะเพิ่มที่นี่"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"รับทราบ"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"วิดเจ็ต"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"หากต้องการเพิ่มทางลัด \"วิดเจ็ต\" โปรดตรวจสอบว่าได้เปิดใช้ \"แสดงวิดเจ็ตในหน้าจอล็อก\" แล้วในการตั้งค่า"</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"การตั้งค่า"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"หยุดการแจ้งเตือนชั่วคราวโดย \"ห้ามรบกวน\""</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{ไม่มีการแจ้งเตือน}=1{หยุดการแจ้งเตือนชั่วคราวโดย {mode}}=2{หยุดการแจ้งเตือนชั่วคราวโดย {mode} และโหมดอื่นอีก 1 โหมด}other{หยุดการแจ้งเตือนชั่วคราวโดย {mode} และโหมดอื่นอีก # โหมด}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"เริ่มเลย"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"การติดตามการเคลื่อนไหวของศีรษะ"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"แตะเพื่อเปลี่ยนโหมดเสียงเรียกเข้า"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"โหมดเสียงเรียกเข้า"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ปิดเสียง"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"เปิดเสียง"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"สั่น"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"แป้นพิมพ์ลัด"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ปรับแต่งแป้นพิมพ์ลัด"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"นำแป้นพิมพ์ลัดออกใช่ไหม"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"รีเซ็ตกลับเป็นค่าเริ่มต้นไหม"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"กดแป้นเพื่อกำหนดแป้นพิมพ์ลัด"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"การดำเนินการนี้จะลบแป้นพิมพ์ลัดที่กำหนดเองอย่างถาวร"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"การดำเนินการนี้จะลบทางลัดที่กำหนดเองทั้งหมดอย่างถาวร"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ค้นหาแป้นพิมพ์ลัด"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ไม่พบผลการค้นหา"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ไอคอนยุบ"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"การตั้งค่าแป้นพิมพ์"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ตั้งค่าแป้นพิมพ์ลัด"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"นำออก"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"ใช่ รีเซ็ต"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ยกเลิก"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"กดแป้น"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"มีการใช้แป้นที่กดร่วมกันนี้แล้ว โปรดลองใช้แป้นอื่น"</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"กดปุ่มดำเนินการบนแป้นพิมพ์"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ยอดเยี่ยม"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"คุณทำท่าทางสัมผัสเพื่อดูแอปทั้งหมดสำเร็จแล้ว"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ไฟแบ็กไลต์ของแป้นพิมพ์"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"ระดับที่ %1$d จาก %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ระบบควบคุมอุปกรณ์สมาร์ทโฮม"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 76375a3..9d79424 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para magbukas ng app gamit ang isang widget, kakailanganin mong i-verify na ikaw iyan. Bukod pa rito, tandaang puwedeng tingnan ng kahit na sino ang mga ito, kahit na naka-lock ang iyong tablet. Posibleng hindi para sa iyong lock screen ang ilang widget at posibleng hindi ligtas ang mga ito na idagdag dito."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Mga Widget"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Para idagdag ang shortcut na \"Mga Widget,\" tiyaking naka-enable ang \"Ipakita ang mga widget sa lock screen\" sa mga setting."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Mga Setting"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Magpalit ng user"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ide-delete ang lahat ng app at data sa session na ito."</string>
@@ -593,6 +591,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Mga Notification"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Mga Pag-uusap"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"I-clear ang lahat ng silent na notification"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Mga notification na na-pause ng Huwag Istorbohin"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Walang notification}=1{Na-pause ng {mode} ang mga notification}=2{Na-pause ng {mode} at isa pang mode ang mga notification}one{Na-pause ng {mode} at # pang mode ang mga notification}other{Na-pause ng {mode} at # pang mode ang mga notification}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Magsimula ngayon"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Pag-track ng Ulo"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"I-tap para baguhin ang ringer mode"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"ringer mode"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"i-mute"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"i-unmute"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"i-vibrate"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Mga keyboard shortcut"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"I-customize ang mga keyboard shortcut"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Alisin ang shortcut?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"I-reset pabalik sa default?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pindutin ang key para magtalaga ng shortcut"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Permanente nitong ide-delete ang iyong custom na shortcut."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Permanente nitong ide-delete ang lahat ng iyong custom na shortcut."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Mga shortcut ng paghahanap"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Walang resulta ng paghahanap"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"I-collapse ang icon"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Mga Setting ng Keyboard"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Magtakda ng shortcut"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Alisin"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Oo, i-reset"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Kanselahin"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pindutin ang key"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Ginagamit na ang kumbinasyon ng key. Sumubok ng ibang key."</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pindutin ang action key sa iyong keyboard"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Magaling!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Nakumpleto mo ang galaw sa pag-view ng lahat ng app"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Backlight ng keyboard"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d sa %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Mga Home Control"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index e1484e3..046d973 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Bildirimler"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Görüşmeler"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Sessiz bildirimlerin tümünü temizle"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bildirimler, Rahatsız Etmeyin özelliği tarafından duraklatıldı"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Bildirim yok}=1{Bildirimler {mode} tarafından duraklatıldı}=2{Bildirimler, {mode} ve bir diğer mod tarafından duraklatıldı}other{Bildirimler, {mode} ve # diğer mod tarafından duraklatıldı}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Şimdi başlat"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Baş Takibi"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Telefon zili modunu değiştirmek için dokunun"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"telefon zili modu"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"sesi  kapat"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"sesi aç"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"titreşim"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Klavyenizde eylem tuşuna basın"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Tebrikler!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Tüm uygulamaları görüntüleme hareketini tamamladınız"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klavye aydınlatması"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Seviye %1$d / %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Ev Kontrolleri"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index e4cc156..a414824 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Режим \"Не турбувати\" призупинив сповіщення"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Немає сповіщень}=1{Режим \"{mode}\" призупинив надсилання сповіщень}=2{\"{mode}\" і ще один режим призупинили надсилання сповіщень}one{\"{mode}\" і ще # режим призупинили надсилання сповіщень}few{\"{mode}\" і ще # режими призупинили надсилання сповіщень}many{\"{mode}\" і ще # режимів призупинили надсилання сповіщень}other{\"{mode}\" і ще # режиму призупинили надсилання сповіщень}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Почати зараз"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Відстеження рухів голови"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Торкніться, щоб змінити режим дзвінка"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"режим дзвінка"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"вимкнути звук"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"увімкнути звук"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"увімкнути вібросигнал"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Натисніть клавішу дії на клавіатурі"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Чудово!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Ви виконали жест для перегляду всіх додатків"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Підсвічування клавіатури"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Рівень %1$d з %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Автоматизація дому"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index def8806..2980b2f 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ویجیٹ کے ذریعے ایپ کھولنے کے لیے آپ کو تصدیق کرنی ہوگی کہ یہ آپ ہی ہیں۔ نیز، ذہن میں رکھیں کہ کوئی بھی انہیں دیکھ سکتا ہے، یہاں تک کہ جب آپ کا ٹیبلیٹ مقفل ہو۔ ہو سکتا ہے کچھ ویجٹس آپ کی لاک اسکرین کے لیے نہ بنائے گئے ہوں اور یہاں شامل کرنا غیر محفوظ ہو سکتا ہے۔"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"سمجھ آ گئی"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"ویجیٹس"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"ویجیٹس\" شارٹ کٹ شامل کرنے کے لیے، یقینی بنائیں کہ \"مقفل اسکرین پر ویجیٹس دکھائیں\" ترتیبات میں فعال ہے۔"</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"ترتیبات"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ڈسٹرب نہ کریں\' کے ذریعے اطلاعات کو موقوف کیا گیا"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{کوئی اطلاع نہیں ہے}=1{{mode} کی طرف سے اطلاعات کو روک دیا گیا ہے}=2{{mode} اور ایک دوسرے موڈ کے ذریعہ اطلاعات کو روک دیا گیا ہے}other{{mode} اور # دیگر طریقوں کے ذریعے اطلاعات کو روک دیا گیا ہے}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ابھی شروع کریں"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"سر کی ٹریکنگ"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"رنگر وضع تبدیل کرنے کیلئے تھپتھپائیں"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"رنگر موڈ"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"خاموش کریں"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"غیر خاموش کریں"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"وائبریٹ"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"کی بورڈ شارٹ کٹس"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"کی بورڈ شارٹ کٹس کو حسب ضرورت بنائیں"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"شارٹ کٹ ہٹائیں؟"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ڈیفالٹ پر واپس ری سیٹ کریں؟"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"شارٹ کٹ تفویض کرنے کے لیے کلید کو دبائیں"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"یہ آپ کا حسب ضرورت شارٹ کٹ مستقل طور پر حذف کر دے گا۔"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"یہ آپ کے تمام حسب ضرورت شارٹ کٹس کو مستقل طور پر حذف کر دے گا۔"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"تلاش کے شارٹ کٹس"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"تلاش کا کوئی نتیجہ نہیں ہے"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"آئیکن سکیڑیں"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"کی بورڈ کی ترتیبات"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"شارٹ کٹ سیٹ کریں"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"ہٹائیں"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"ہاں، ری سیٹ کریں"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"منسوخ کریں"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"کلید کو دبائیں"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"کلیدی مجموعہ پہلے سے استعمال میں ہے۔ دوسری کلید آزمائیں۔"</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"اپنے کی بورڈ پر ایکشن کلید دبائیں"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"بہت خوب!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"آپ نے سبھی ایپس دیکھیں کا اشارہ مکمل کر لیا ہے"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"کی بورڈ بیک لائٹ"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"‏%2$d میں سے ‎%1$d کا لیول"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ہوم کنٹرولز"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 9dab9e1..9057926 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ilovani vidjet orqali ochish uchun shaxsingizni tasdiqlashingiz kerak. Shuningdek, planshet qulflanganda ham bu axborotlar hammaga koʻrinishini unutmang. Ayrim vidjetlar ekran qulfiga moslanmagan va ularni bu yerda chiqarish xavfli boʻlishi mumkin."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Vidjetlar"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"“Vidjetlar” yorligʻini qoʻshish uchun sozlamalarda “Vidjetlarni ekran qulfida chiqarish” yoqilganini tekshiring."</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Sozlamalar"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Foydalanuvchini almashtirish"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"tortib tushiriladigan menyu"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ushbu seansdagi barcha ilovalar va ma’lumotlar o‘chirib tashlanadi."</string>
@@ -593,6 +591,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Bildirishnomalar"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Suhbatlar"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Barcha sokin bildirishnomalarni tozalash"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bezovta qilinmasin rejimida bildirishnomalar pauza qilinadi"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Bildirishnomalar yoʻq}=1{{mode} rejimi bildirishnomalarni pauza qilgan}=2{{mode} va yana bitta boshqa rejim bildirishnomalarni pauza qilgan}other{{mode} va # ta boshqa rejim bildirishnomalarni pauza qilgan}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Boshlash"</string>
@@ -707,6 +707,7 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Boshni kuzatish"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Jiringlagich rejimini oʻzgartirish uchun bosing"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"jiringlagich rejimi"</string>
+    <string name="volume_ringer_drawer_closed_content_description" msgid="4737792429808781745">"<xliff:g id="VOLUME_RINGER_STATUS">%1$s</xliff:g>, jiringlagich rejimini oʻzgartirish uchun bosing"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ovozsiz qilish"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ovozni yoqish"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"tebranish"</string>
@@ -1426,20 +1427,17 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Tezkor tugmalar"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tezkor tugmalarni moslash"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Tezkor tugma olib tashlansinmi?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Asliga qaytarilsinmi?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Tezkor tugma sozlash uchun tugmani bosing"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Bunda maxsus tezkor tugma butunlay oʻchirib tashlanadi."</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Bunda barcha maxsus yorliqlaringiz butunlay oʻchirib tashlanadi."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tezkor tugmalar qidiruvi"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Hech narsa topilmadi"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Yigʻish belgisi"</string>
     <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Amal bajarish uchun Meta tugmasi belgisi"</string>
     <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plus belgisi"</string>
     <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Moslash"</string>
-    <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
-    <skip />
+    <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Tiklash"</string>
     <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Tayyor"</string>
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Yoyish belgisi"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"yoki"</string>
@@ -1449,8 +1447,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klaviatura sozlamalari"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Tezkor tugma sozlash"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Olib tashlash"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Ha, asliga qaytarilsin"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Bekor qilish"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tugmani bosing"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Bu tugmalar birikmasi band. Boshqasini ishlating."</string>
@@ -1482,6 +1479,7 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Klaviaturadagi amal tugmasini bosing"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Barakalla!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Hamma ilovalarni koʻrish ishorasini tugalladingiz"</string>
+    <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Qoʻllanma animatsiyasi, pauza qilish va ijroni davom ettirish uchun bosing."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatura orqa yoritkichi"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Daraja: %1$d / %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Uy boshqaruvi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index c709a31..6c7c5f6 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Thông báo"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Cuộc trò chuyện"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Xóa tất cả thông báo im lặng"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Chế độ Không làm phiền đã tạm dừng thông báo"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Không có thông báo}=1{{mode} đã tạm dừng thông báo}=2{{mode} và một chế độ khác đã tạm dừng thông báo}other{{mode} và # chế độ khác đã tạm dừng thông báo}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Bắt đầu ngay"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Theo dõi chuyển động của đầu"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Nhấn để thay đổi chế độ chuông"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"chế độ chuông"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"tắt tiếng"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"bật tiếng"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"rung"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Nhấn phím hành động trên bàn phím"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Rất tốt!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Bạn đã hoàn tất cử chỉ xem tất cả các ứng dụng"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Đèn nền bàn phím"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Độ sáng %1$d/%2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Điều khiển nhà"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index a106507..d37fe90 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -529,10 +529,8 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"若要使用微件打开应用,您需要验证是您本人在操作。另外请注意,任何人都可以查看此类微件,即使您的平板电脑已锁定。有些微件可能不适合显示在锁定的屏幕中,因此添加到这里可能不安全。"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"知道了"</string>
     <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"微件"</string>
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
-    <skip />
-    <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
-    <skip />
+    <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"如要添加“微件”快捷方式,请确保已在设置中启用“在锁屏状态下显示微件”。"</string>
+    <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"设置"</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>
@@ -593,6 +591,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"勿扰模式暂停的通知"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{无通知}=1{{mode}暂停了通知}=2{{mode}和另外 1 种模式暂停了通知}other{{mode}和另外 # 种模式暂停了通知}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"立即开始"</string>
@@ -707,6 +707,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"头部跟踪"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"点按即可更改振铃器模式"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"响铃模式"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"静音"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消静音"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"振动"</string>
@@ -1426,12 +1428,10 @@
     <string name="shortcut_helper_title" msgid="8567500639300970049">"键盘快捷键"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自定义键盘快捷键"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"要移除快捷键吗?"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"要重置为默认快捷方式吗?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"按下按键即可指定快捷键"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"此操作会永久删除您的自定义快捷键。"</string>
-    <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
-    <skip />
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"此操作会永久删除您的所有自定义快捷方式。"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜索快捷键"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"无搜索结果"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收起图标"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"键盘设置"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"设置快捷键"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"移除"</string>
-    <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
-    <skip />
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"是,重置"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"取消"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"按下按键"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"按键组合已被使用,请尝试使用其他按键。"</string>
@@ -1482,6 +1481,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"按键盘上的快捷操作按键"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"非常棒!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"您已完成“查看所有应用”手势教程"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"键盘背光"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 级,共 %2$d 级"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"家居控制"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index afbd411..9b16360 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"「請勿騷擾」模式已將通知暫停"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{沒有通知}=1{{mode}已暫停通知}=2{{mode}和另外一個模式已暫停通知}other{{mode}和另外 # 個模式已暫停通知}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"頭部追蹤"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"輕按即可變更響鈴模式"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"響鈴模式"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"靜音"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消靜音"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"震動"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"按下鍵盤上的快捷操作鍵"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"做得好!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"你已完成「查看所有應用程式」手勢的教學課程"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"鍵盤背光"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 級,共 %2$d 級"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"智能家居"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 03d70e1..49111ea 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -593,6 +593,8 @@
     <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>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"「零打擾」模式已將通知設為暫停"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{沒有通知}=1{「{mode}」模式已將通知設為暫停}=2{「{mode}」和另一個模式已將通知設為暫停}other{「{mode}」和另外 # 個模式已將通知設為暫停}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"頭部追蹤"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"輕觸即可變更鈴聲模式"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"鈴聲模式"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"靜音"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消靜音"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"震動"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"按下鍵盤上的快捷操作鍵"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"非常好!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"你已完成「查看所有應用程式」手勢教學課程"</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"鍵盤背光"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 級,共 %2$d 級"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"居家控制"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index b39c3e9..9d4f70c 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -593,6 +593,8 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Izaziso"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Izingxoxo"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Sula zonke izaziso ezithulile"</string>
+    <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+    <skip />
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Izaziso zimiswe okwesikhashana ukungaphazamisi"</string>
     <string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Azikho izaziso}=1{Izaziso zimiswe okwesikhashana yi-{mode}}=2{Izaziso zimiswe okwesikhashana yi-{mode} nelinye imodi elilodwa}one{Izaziso zimiswe okwesikhashana yi-{mode} kanye namanye amamodi angu-#}other{Izaziso zimiswe okwesikhashana yi-{mode} kanye namanye amamodi angu-#}}"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Qala manje"</string>
@@ -707,6 +709,8 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Ukulandelela Ikhanda"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Thepha ukuze ushintshe imodi yokukhala"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"imodi yokukhala"</string>
+    <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+    <skip />
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"thulisa"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"susa ukuthula"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"dlidliza"</string>
@@ -1482,6 +1486,8 @@
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Cindezela inkinobho yokufinyelela kukhibhodi yakho"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Wenze kahle!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Uqedele ukunyakazisa kokubuka onke ama-app."</string>
+    <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+    <skip />
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Ilambu lekhibhodi"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Ileveli %1$d ka-%2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Izilawuli Zasekhaya"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index a375264..28df2e2 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -124,7 +124,7 @@
     <!-- Keyboard shortcuts colors -->
     <color name="ksh_application_group_color">#fff44336</color>
     <color name="ksh_key_item_color">@*android:color/system_on_surface_variant_light</color>
-    <color name="ksh_key_item_background">?androidprv:attr/materialColorSurfaceContainerHighest</color>
+    <color name="ksh_key_item_background">@androidprv:color/materialColorSurfaceContainerHighest</color>
 
     <color name="instant_apps_color">#ff4d5a64</color>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index df7adc0..5894f29 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1224,6 +1224,9 @@
     <dimen name="min_window_blur_radius">1px</dimen>
     <dimen name="max_window_blur_radius">23px</dimen>
 
+    <!-- Blur radius behind Notification Shade -->
+    <dimen name="max_shade_window_blur_radius">60dp</dimen>
+
     <!-- How much into a DisplayCutout's bounds we can go, on each side -->
     <dimen name="display_cutout_margin_consumption">0px</dimen>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 658f2c2..f927e26 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1342,6 +1342,8 @@
     <string name="glanceable_hub_lockscreen_affordance_disabled_text">To add the \"Widgets\" shortcut, make sure \"Show widgets on lock screen\" is enabled in settings.</string>
     <!-- Label for a button used to open Settings in order to enable showing widgets on the lock screen. [CHAR LIMIT=NONE] -->
     <string name="glanceable_hub_lockscreen_affordance_action_button_label">Settings</string>
+    <!-- Content description for a "show screensaver" button on glanceable hub. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_glanceable_hub_to_dream_button">Show screensaver button</string>
 
     <!-- Related to user switcher --><skip/>
 
@@ -1948,6 +1950,21 @@
     <!-- Text displayed indicating that the user might be able to use satellite SOS. -->
     <string name="satellite_emergency_only_carrier_text">Emergency calls or SOS</string>
 
+    <!-- Content description skeleton. Input strings should be carrier name and signal bar description [CHAR LIMIT=NONE]-->
+    <string name="accessibility_phone_string_format"><xliff:g id="carrier_name" example="Carrier Name">%1$s</xliff:g>, <xliff:g id="signal_strength_description" example="two bars">%2$s</xliff:g>.</string>
+    <!-- Content description describing 0 signal bars. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_no_signal">no signal</string>
+    <!-- Content description describing 1 signal bar. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_one_bar">one bar</string>
+    <!-- Content description describing 2 signal bars. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_two_bars">two bars</string>
+    <!-- Content description describing 3 signal bars. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_three_bars">three bars</string>
+    <!-- Content description describing 4 signal bars. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_four_bars">four bars</string>
+    <!-- Content description describing full signal bars. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_signal_full">signal full</string>
+
     <!-- Accessibility label for managed profile icon (not shown on screen) [CHAR LIMIT=NONE] -->
     <string name="accessibility_managed_profile">Work profile</string>
 
@@ -2044,8 +2061,9 @@
     <!-- Text shown in notification guts for conversation notifications that don't implement the full feature -->
     <string name="no_shortcut"><xliff:g id="app_name" example="YouTube">%1$s</xliff:g> doesn\u2019t support conversation features</string>
 
+    <!-- TODO: b/381099727 - Mark translatable once feedback layout is finalized. -->
     <!-- [CHAR LIMIT=80] Text shown in feedback button in notification guts for a bundled notification -->
-    <string name="notification_guts_bundle_feedback">Provide Bundle Feedback</string>
+    <string name="notification_guts_bundle_feedback" translatable="false">Provide Bundle Feedback</string>
 
     <!-- Notification: Control panel: Label that displays when the app's notifications cannot be blocked. -->
     <string name="notification_unblockable_desc">These notifications can\'t be modified.</string>
@@ -2280,11 +2298,11 @@
     <!-- 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>
+    <string name="system_multitasking_rhs">Use split screen with 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>
+    <string name="system_multitasking_lhs">Use split screen with 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>
+    <string name="system_multitasking_full_screen">Switch 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] -->
     <string name="system_multitasking_splitscreen_focus_rhs">Switch to app on right or below while using split screen</string>
     <!-- User visible title for the keyboard shortcut that switches to app on left or above while using split screen [CHAR LIMIT=70] -->
@@ -2573,8 +2591,6 @@
     <!-- Tuner string -->
     <!-- Tuner string -->
 
-    <!-- Message shown during shutdown when Find My Device with Dead Battery Finder is active  [CHAR LIMIT=300] -->
-    <string name="finder_active">You can locate this phone with Find My Device even when powered off</string>
     <!-- Shutdown Progress Dialog. This is shown if the user chooses to power off the phone. [CHAR LIMIT=60] -->
     <string name="shutdown_progress">Shutting down\u2026</string>
 
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 9aa7137..12f6e69 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -151,7 +151,7 @@
 
     <style name="TextAppearance.QS.UserSwitcher">
         <item name="android:textSize">@dimen/qs_tile_text_size</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
     </style>
 
     <!-- This is hard coded to be sans-serif-condensed to match the icons -->
@@ -183,67 +183,46 @@
         <item name="android:textColor">?android:attr/textColorPrimary</item>
     </style>
 
-    <style name="TextAppearance.AuthCredential.OldTitle">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
-        <item name="android:paddingTop">12dp</item>
-        <item name="android:paddingHorizontal">24dp</item>
-        <item name="android:textSize">24sp</item>
-    </style>
-
-    <style name="TextAppearance.AuthCredential.OldSubtitle">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
-        <item name="android:paddingTop">8dp</item>
-        <item name="android:paddingHorizontal">24dp</item>
-        <item name="android:textSize">16sp</item>
-    </style>
-
-    <style name="TextAppearance.AuthCredential.OldDescription">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
-        <item name="android:paddingTop">8dp</item>
-        <item name="android:paddingHorizontal">24dp</item>
-        <item name="android:textSize">14sp</item>
-    </style>
-
     <style name="TextAppearance.AuthCredential.LogoDescription" parent="TextAppearance.Material3.LabelLarge" >
         <item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
-        <item name="android:gravity">@integer/biometric_dialog_text_gravity</item>
+        <item name="android:gravity">center_horizontal</item>
         <item name="android:maxLines">1</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
         <item name="android:ellipsize">end</item>
     </style>
 
     <style name="TextAppearance.AuthCredential.Title" parent="TextAppearance.Material3.HeadlineSmall" >
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.AuthCredential.Subtitle" parent="TextAppearance.Material3.BodyMedium" >
         <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.AuthCredential.Description" parent="TextAppearance.Material3.BodyMedium" >
         <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.AuthCredential.VerticalListContentViewDescription" parent="TextAppearance.Material3.TitleSmall">
         <item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.AuthCredential.ContentViewWithButtonDescription" parent="TextAppearance.AuthCredential.Description" />
 
     <style name="TextAppearance.AuthCredential.ContentViewListItem" parent="TextAppearance.Material3.BodySmall">
         <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+        <item name="android:textColor">@androidprv:color/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">
         <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
         <item name="android:marqueeRepeatLimit">marquee_forever</item>
         <item name="android:singleLine">true</item>
         <item name="android:ellipsize">marquee</item>
@@ -269,21 +248,21 @@
         <item name="android:layout_marginTop">24dp</item>
         <item name="android:textSize">36dp</item>
         <item name="android:focusable">true</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.AuthNonBioCredential.Subtitle">
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:layout_marginTop">20dp</item>
         <item name="android:textSize">18sp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.AuthNonBioCredential.Description">
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:layout_marginTop">20dp</item>
         <item name="android:textSize">18sp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.AuthNonBioCredential.Error">
@@ -352,7 +331,7 @@
     </style>
 
     <style name="AuthNonCredentialPanelStyle">
-        <item name="android:background">?androidprv:attr/materialColorSurfaceBright</item>
+        <item name="android:background">@androidprv:color/materialColorSurfaceBright</item>
     </style>
 
     <style name="AuthCredentialPanelStyle" parent="AuthNonCredentialPanelStyle">
@@ -383,13 +362,13 @@
         <item name="android:minWidth">48dp</item>
         <item name="android:paddingLeft">0dp</item>
         <item name="android:paddingRight">12dp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorPrimary</item>
+        <item name="android:textColor">@androidprv:color/materialColorPrimary</item>
     </style>
 
     <style name="AuthCredentialNegativeButtonStyle" parent="TextAppearance.Material3.LabelLarge">
         <item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
         <item name="android:background">@color/transparent</item>
-        <item name="android:textColor">?androidprv:attr/materialColorPrimary</item>
+        <item name="android:textColor">@androidprv:color/materialColorPrimary</item>
     </style>
 
     <style name="DeviceManagementDialogTitle">
@@ -411,7 +390,7 @@
     </style>
 
     <style name="KeyboardShortcutHelper.BottomSheet.DragHandle" parent="Widget.Material3.BottomSheet.DragHandle">
-        <item name="tint">?androidprv:attr/materialColorOutlineVariant</item>
+        <item name="tint">@androidprv:color/materialColorOutlineVariant</item>
     </style>
 
     <style name="KeyboardShortcutHelper.BottomSheetDialogAnimation">
@@ -510,23 +489,23 @@
         <item name="android:windowIsFloating">true</item>
         <item name="android:homeAsUpIndicator">@drawable/ic_arrow_back</item>
 
-        <item name="surfaceBright">?androidprv:attr/materialColorSurfaceBright</item>
+        <item name="surfaceBright">@androidprv:color/materialColorSurfaceBright</item>
         <item name="android:colorBackground">?attr/surfaceBright</item>
-        <item name="scHigh">?androidprv:attr/materialColorSurfaceContainerHigh</item>
-        <item name="primary">?androidprv:attr/materialColorPrimary</item>
-        <item name="tertiary">?androidprv:attr/materialColorTertiary</item>
-        <item name="onSurface">?androidprv:attr/materialColorOnSurface</item>
-        <item name="onSurfaceVariant">?androidprv:attr/materialColorOnSurfaceVariant</item>
-        <item name="outline">?androidprv:attr/materialColorOutline</item>
+        <item name="scHigh">@androidprv:color/materialColorSurfaceContainerHigh</item>
+        <item name="primary">@androidprv:color/materialColorPrimary</item>
+        <item name="tertiary">@androidprv:color/materialColorTertiary</item>
+        <item name="onSurface">@androidprv:color/materialColorOnSurface</item>
+        <item name="onSurfaceVariant">@androidprv:color/materialColorOnSurfaceVariant</item>
+        <item name="outline">@androidprv:color/materialColorOutline</item>
 
-        <item name="shadeActive">?androidprv:attr/customColorShadeActive</item>
-        <item name="onShadeActive">?androidprv:attr/customColorOnShadeActive</item>
-        <item name="onShadeActiveVariant">?androidprv:attr/customColorOnShadeActiveVariant</item>
-        <item name="shadeInactive">?androidprv:attr/customColorShadeInactive</item>
-        <item name="onShadeInactive">?androidprv:attr/customColorOnShadeInactive</item>
-        <item name="onShadeInactiveVariant">?androidprv:attr/customColorOnShadeInactiveVariant</item>
-        <item name="shadeDisabled">?androidprv:attr/customColorShadeDisabled</item>
-        <item name="underSurface">?androidprv:attr/customColorUnderSurface</item>
+        <item name="shadeActive">@androidprv:color/customColorShadeActive</item>
+        <item name="onShadeActive">@androidprv:color/customColorOnShadeActive</item>
+        <item name="onShadeActiveVariant">@androidprv:color/customColorOnShadeActiveVariant</item>
+        <item name="shadeInactive">@androidprv:color/customColorShadeInactive</item>
+        <item name="onShadeInactive">@androidprv:color/customColorOnShadeInactive</item>
+        <item name="onShadeInactiveVariant">@androidprv:color/customColorOnShadeInactiveVariant</item>
+        <item name="shadeDisabled">@androidprv:color/customColorShadeDisabled</item>
+        <item name="underSurface">@androidprv:color/customColorUnderSurface</item>
         <item name="android:itemTextAppearance">@style/Control.MenuItem</item>
     </style>
 
@@ -588,7 +567,7 @@
         <item name="android:buttonBarPositiveButtonStyle">@style/Widget.Dialog.Button</item>
         <item name="android:buttonBarNegativeButtonStyle">@style/Widget.Dialog.Button.BorderButton</item>
         <item name="android:buttonBarNeutralButtonStyle">@style/Widget.Dialog.Button.BorderButton</item>
-        <item name="android:colorBackground">?androidprv:attr/materialColorSurfaceBright</item>
+        <item name="android:colorBackground">@androidprv:color/materialColorSurfaceBright</item>
         <item name="android:alertDialogStyle">@style/ScrollableAlertDialogStyle</item>
         <item name="android:buttonBarStyle">@style/ButtonBarStyle</item>
         <item name="android:buttonBarButtonStyle">@style/Widget.Dialog.Button.Large</item>
@@ -744,34 +723,34 @@
     <style name="TextAppearance.NotificationImportanceChannel">
         <item name="android:textSize">@dimen/notification_importance_channel_text</item>
         <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
         <item name="android:textSize">@dimen/notification_importance_channel_text</item>
     </style>
 
     <style name="TextAppearance.NotificationImportanceChannelGroup">
         <item name="android:textSize">@dimen/notification_importance_channel_group_text</item>
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
         <item name="android:textSize">@dimen/notification_importance_channel_group_text</item>
     </style>
 
     <style name="TextAppearance.NotificationImportanceApp">
         <item name="android:textSize">@dimen/notification_importance_channel_group_text</item>
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
         <item name="android:textSize">@dimen/notification_importance_channel_group_text</item>
     </style>
 
     <style name="TextAppearance.NotificationImportanceHeader">
         <item name="android:textSize">@dimen/notification_importance_header_text</item>
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.NotificationImportanceDetail">
         <item name="android:textSize">@dimen/notification_importance_description_text</item>
         <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
         <item name="android:gravity">center</item>
     </style>
 
@@ -785,7 +764,7 @@
     <style
         name="TextAppearance.NotificationSectionHeaderLabel"
         parent="@android:style/Widget.DeviceDefault.Button.Borderless">
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
         <item name="android:textAllCaps">false</item>
         <item name="android:textSize">14sp</item>
         <item name="android:minWidth">0dp</item>
@@ -794,7 +773,7 @@
     <style
         name="TextAppearance.NotificationSectionHeaderButton"
         parent="@android:style/Widget.DeviceDefault.Button.Borderless">
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
         <item name="android:textAllCaps">false</item>
         <item name="android:textSize">14sp</item>
         <item name="android:minWidth">0dp</item>
@@ -803,7 +782,7 @@
     <style
         name="TextAppearance.NotificationFooterButton"
         parent="@android:style/Widget.DeviceDefault.Button.Borderless">
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
         <item name="android:textAllCaps">false</item>
         <item name="android:textSize">14sp</item>
         <item name="android:minWidth">0dp</item>
@@ -812,8 +791,8 @@
     <style
         name="TextAppearance.NotificationFooterButtonRedesign"
         parent="@android:style/Widget.DeviceDefault.Button.Borderless">
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
-        <item name="android:drawableTint">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
+        <item name="android:drawableTint">@androidprv:color/materialColorOnSurface</item>
         <item name="android:textAllCaps">false</item>
         <item name="android:textSize">16sp</item>
         <item name="android:minWidth">0dp</item>
@@ -1009,12 +988,12 @@
     </style>
 
     <style name="LongScreenshotActivity" parent="@android:style/Theme.DeviceDefault.DayNight">
-        <item name="android:colorBackground">?androidprv:attr/materialColorSurfaceContainer</item>
+        <item name="android:colorBackground">@androidprv:color/materialColorSurfaceContainer</item>
         <item name="android:windowNoTitle">true</item>
         <item name="android:windowLightStatusBar">true</item>
         <item name="android:windowLightNavigationBar">true</item>
-        <item name="android:statusBarColor">?androidprv:attr/materialColorSurfaceContainer</item>
-        <item name="android:navigationBarColor">?androidprv:attr/materialColorSurfaceContainerHighest</item>
+        <item name="android:statusBarColor">@androidprv:color/materialColorSurfaceContainer</item>
+        <item name="android:navigationBarColor">@androidprv:color/materialColorSurfaceContainerHighest</item>
         <item name="android:windowActivityTransitions">true</item>
     </style>
 
@@ -1092,7 +1071,7 @@
 
     <style name="Theme.VolumePanel.Popup" parent="@style/Theme.SystemUI.Dialog">
         <item name="android:dialogCornerRadius">44dp</item>
-        <item name="android:colorBackground">?androidprv:attr/materialColorSurfaceContainerHigh
+        <item name="android:colorBackground">@androidprv:color/materialColorSurfaceContainerHigh
         </item>
     </style>
 
@@ -1303,7 +1282,7 @@
     </style>
 
     <style name="TextAppearance.Dialog.Title" parent="@android:style/TextAppearance.DeviceDefault.Large">
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
         <item name="android:textSize">@dimen/dialog_title_text_size</item>
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:lineHeight">32sp</item>
@@ -1313,7 +1292,7 @@
     </style>
 
     <style name="TextAppearance.Dialog.Body" parent="@android:style/TextAppearance.DeviceDefault.Medium">
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
         <item name="android:textSize">14sp</item>
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:lineHeight">20sp</item>
@@ -1408,7 +1387,7 @@
 
     <style name="InternetDialog.NetworkTitle.Active">
         <item name="android:textAppearance">@style/TextAppearance.InternetDialog.Active</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnPrimaryContainer</item>
     </style>
 
     <style name="InternetDialog.NetworkSummary">
@@ -1421,27 +1400,27 @@
     <style name="InternetDialog.NetworkSummary.Active">
         <item name="android:textAppearance">@style/TextAppearance.InternetDialog.Secondary.Active
         </item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnPrimaryContainer</item>
     </style>
 
     <style name="TextAppearance.InternetDialog">
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:textSize">16sp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
         <item name="android:textDirection">locale</item>
     </style>
 
     <style name="TextAppearance.InternetDialog.Secondary">
         <item name="android:textSize">14sp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
     </style>
 
     <style name="TextAppearance.InternetDialog.Active">
-        <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnPrimaryContainer</item>
     </style>
 
     <style name="TextAppearance.InternetDialog.Secondary.Active">
-        <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnPrimaryContainer</item>
     </style>
 
     <style name="FgsManagerDialogTitle">
@@ -1478,18 +1457,18 @@
         <item name="android:orientation">horizontal</item>
         <item name="android:focusable">true</item>
         <item name="android:clickable">true</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.BluetoothTileDialog">
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:textDirection">locale</item>
         <item name="android:textAlignment">gravity</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.BluetoothTileDialog.Active">
-        <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnPrimaryContainer</item>
     </style>
 
     <style name="BluetoothTileDialog.AudioSharingButton" parent="Widget.Dialog.Button">
@@ -1686,7 +1665,7 @@
     <style name="ShortCutButton" parent="@android:style/Widget.Material.Button">
         <item name="android:background">@drawable/shortcut_button_colored</item>
         <item name="android:textSize">16sp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
         <item name="android:layout_marginEnd">12dp</item>
         <item name="android:paddingLeft">24dp</item>
         <item name="android:paddingRight">24dp</item>
@@ -1712,18 +1691,18 @@
         parent="@android:style/TextAppearance.DeviceDefault.Medium">
         <item name="android:textSize">14sp</item>
         <item name="android:lineHeight">20sp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.PrivacyDialog.Item.Summary"
         parent="@android:style/TextAppearance.DeviceDefault.Small">
         <item name="android:textSize">14sp</item>
         <item name="android:lineHeight">20sp</item>
-        <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+        <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
     </style>
 
     <style name="Theme.PrivacyDialog" parent="@style/Theme.SystemUI.Dialog">
-        <item name="android:colorBackground">?androidprv:attr/materialColorSurfaceContainer</item>
+        <item name="android:colorBackground">@androidprv:color/materialColorSurfaceContainer</item>
     </style>
 
     <style name="Theme.SystemUI.Dialog.StickyKeys" parent="@style/Theme.SystemUI.Dialog">
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
index 9e8cabf..8576a6e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
@@ -330,6 +330,11 @@
     }
 
     @Override
+    public int hashCode() {
+        return key.hashCode();
+    }
+
+    @Override
     public String toString() {
         return "[" + key.toString() + "] " + title;
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt b/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
index 495367b..842efa3 100644
--- a/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
+++ b/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
@@ -25,7 +25,6 @@
 import android.util.AttributeSet
 import android.view.View
 import com.android.app.animation.Interpolators
-import com.android.settingslib.Utils
 import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.TITLE
 
 /** Displays security messages for the keyguard bouncer. */
@@ -71,12 +70,12 @@
     }
 
     override fun onThemeChanged() {
-        mDefaultColorState = getColorInStyle() ?: Utils.getColorAttr(context, TITLE)
+        mDefaultColorState = getColorInStyle() ?: ColorStateList.valueOf(context.getColor(TITLE))
         super.onThemeChanged()
     }
 
     override fun reloadColor() {
-        mDefaultColorState = getColorInStyle() ?: Utils.getColorAttr(context, TITLE)
+        mDefaultColorState = getColorInStyle() ?: ColorStateList.valueOf(context.getColor(TITLE))
         super.reloadColor()
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index fcaccd2..36afe1e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -346,8 +346,8 @@
         setPadding(getPaddingLeft(), getPaddingTop() + getResources().getDimensionPixelSize(
                         R.dimen.keyguard_security_container_padding_top), getPaddingRight(),
                 getPaddingBottom());
-        setBackgroundColor(Utils.getColorAttrDefaultColor(getContext(),
-                com.android.internal.R.attr.materialColorSurfaceDim));
+        setBackgroundColor(
+                getContext().getColor(com.android.internal.R.color.materialColorSurfaceDim));
     }
 
     void onResume(SecurityMode securityMode, boolean faceAuthEnabled) {
@@ -814,8 +814,8 @@
 
     void reloadColors() {
         mViewMode.reloadColors();
-        setBackgroundColor(Utils.getColorAttrDefaultColor(getContext(),
-                com.android.internal.R.attr.materialColorSurfaceDim));
+        setBackgroundColor(getContext().getColor(
+                com.android.internal.R.color.materialColorSurfaceDim));
     }
 
     /** Handles density or font scale changes. */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
index 392abf2..0942353 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
@@ -20,7 +20,6 @@
 import android.util.AttributeSet
 import android.widget.ImageView
 import androidx.core.graphics.drawable.DrawableCompat
-import com.android.settingslib.Utils
 import com.android.systemui.res.R
 import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.EMERGENCY_BUTTON
 
@@ -45,7 +44,7 @@
 
     override fun reloadColors() {
         super.reloadColors()
-        val imageColor = Utils.getColorAttrDefaultColor(context, EMERGENCY_BUTTON)
+        val imageColor = context.getColor(EMERGENCY_BUTTON)
         simImageView?.let {
             val wrappedDrawable = DrawableCompat.wrap(it.drawable)
             DrawableCompat.setTint(wrappedDrawable, imageColor)
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
index e773416..dccf53a 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
@@ -15,13 +15,11 @@
  */
 package com.android.keyguard;
 
-import static com.android.settingslib.Utils.getColorAttrDefaultColor;
 import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_BACKGROUND;
 import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_BACKGROUND_PRESSED;
 import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_BUTTON;
 import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_KEY;
 import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_PRESSED;
-import static com.android.systemui.util.ColorUtilKt.getPrivateAttrColorIfUnset;
 
 import android.animation.AnimatorSet;
 import android.animation.ArgbEvaluator;
@@ -127,17 +125,18 @@
         int[] customAttrs = {android.R.attr.colorControlNormal};
         ContextThemeWrapper ctw = new ContextThemeWrapper(context, mStyle);
         @SuppressLint("ResourceType") TypedArray a = ctw.obtainStyledAttributes(customAttrs);
-        mNormalBackgroundColor = getPrivateAttrColorIfUnset(ctw, a, 0, 0,
-                NUM_PAD_BACKGROUND);
+
+        mNormalBackgroundColor = a.getColor(0, context.getColor(NUM_PAD_BACKGROUND));
+
         a.recycle();
 
-        mPressedBackgroundColor = getColorAttrDefaultColor(context, NUM_PAD_BACKGROUND_PRESSED);
-        mTextColorPressed = getColorAttrDefaultColor(context, NUM_PAD_PRESSED);
+        mPressedBackgroundColor = context.getColor(NUM_PAD_BACKGROUND_PRESSED);
+        mTextColorPressed = context.getColor(NUM_PAD_PRESSED);
 
         mBackground.setColor(mNormalBackgroundColor);
         mTextColorPrimary = isNumPadKey
-                ? getColorAttrDefaultColor(context, NUM_PAD_KEY)
-                : getColorAttrDefaultColor(context, NUM_PAD_BUTTON);
+                ? context.getColor(NUM_PAD_KEY)
+                : context.getColor(NUM_PAD_BUTTON);
         createAnimators();
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
index a81c1b0..d7799bf 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
@@ -30,7 +30,6 @@
 
 import androidx.annotation.Nullable;
 
-import com.android.settingslib.Utils;
 import com.android.systemui.res.R;
 
 /**
@@ -101,7 +100,7 @@
         if (mAnimator != null) mAnimator.reloadColors(getContext());
 
         int textColorResId = mIsTransparentMode ? NUM_PAD_KEY : NUM_PAD_BUTTON;
-        int imageColor = Utils.getColorAttrDefaultColor(getContext(), textColorResId);
+        int imageColor = getContext().getColor(textColorResId);
         ((VectorDrawable) getDrawable()).setTintList(ColorStateList.valueOf(imageColor));
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index ebde8a3..e8a702f 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -155,8 +155,7 @@
      * Reload colors from resources.
      **/
     public void reloadColors() {
-        int textColor = Utils.getColorAttr(getContext(), NUM_PAD_KEY)
-                .getDefaultColor();
+        int textColor = getContext().getColor(NUM_PAD_KEY);
         int klondikeColor = Utils.getColorAttr(getContext(), android.R.attr.textColorSecondary)
                 .getDefaultColor();
         mDigitText.setTextColor(textColor);
diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
index 5e9eed9..bac9dac 100644
--- a/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
@@ -28,7 +28,6 @@
 
 import androidx.core.graphics.drawable.DrawableCompat;
 
-import com.android.settingslib.Utils;
 import com.android.systemui.res.R;
 
 /**
@@ -39,8 +38,7 @@
 
     private int mPinLength;
     private int mDotDiameter;
-    private int mColor = Utils.getColorAttr(getContext(), PIN_SHAPES)
-            .getDefaultColor();
+    private int mColor = getContext().getColor(PIN_SHAPES);
     private int mPosition = 0;
     private static final int DEFAULT_PIN_LENGTH = 6;
     private PinShapeAdapter mPinShapeAdapter;
diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
index ee70de3..26a774e 100644
--- a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
@@ -39,7 +39,6 @@
 import androidx.core.graphics.drawable.DrawableCompat;
 
 import com.android.app.animation.Interpolators;
-import com.android.settingslib.Utils;
 import com.android.systemui.res.R;
 
 /**
@@ -49,7 +48,7 @@
 public class PinShapeNonHintingView extends LinearLayout implements PinShapeInput {
     private static final int RESET_STAGGER_DELAY = 40;
     private static final int RESET_MAX_DELAY = 200;
-    private int mColor = Utils.getColorAttr(getContext(), PIN_SHAPES).getDefaultColor();
+    private int mColor = getContext().getColor(PIN_SHAPES);
     private int mPosition = 0;
     private boolean mIsAnimatingReset = false;
     private final PinShapeAdapter mPinShapeAdapter;
diff --git a/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt b/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
index 3abcb13..11ce168 100644
--- a/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
@@ -32,7 +32,6 @@
 import androidx.core.graphics.ColorUtils
 import com.android.app.animation.Interpolators
 import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.settingslib.Utils
 import com.android.systemui.biometrics.AuthController
 import com.android.systemui.log.ScreenDecorationsLogger
 import com.android.systemui.plugins.statusbar.StatusBarStateController
@@ -60,8 +59,8 @@
     private val rimRect = RectF()
     private var cameraProtectionColor = Color.BLACK
 
-    var faceScanningAnimColor = Utils.getColorAttrDefaultColor(context,
-        com.android.internal.R.attr.materialColorPrimaryFixed)
+    var faceScanningAnimColor =
+        context.getColor(com.android.internal.R.color.materialColorPrimaryFixed)
     private var cameraProtectionAnimator: ValueAnimator? = null
     var hideOverlayRunnable: Runnable? = null
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS b/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS
index 1f66c91..1ed8c06 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS
@@ -1,3 +1,4 @@
 # Bug component: 44215
 
-include /core/java/android/view/accessibility/OWNERS
\ No newline at end of file
+include /core/java/android/view/accessibility/OWNERS
+jonesriley@google.com
\ No newline at end of file
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 559e6f7..ffb5f3d 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java
@@ -20,6 +20,7 @@
 import static android.provider.Settings.Secure.ACCESSIBILITY_FLOATING_MENU_MIGRATION_TOOLTIP_PROMPT;
 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 com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
@@ -42,6 +43,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
+import android.view.accessibility.AccessibilityManager;
 
 import androidx.annotation.NonNull;
 
@@ -75,6 +77,9 @@
 
     private final Context mContext;
     private final Configuration mConfiguration;
+    private final AccessibilityManager mAccessibilityManager;
+    private final AccessibilityManager.AccessibilityServicesStateChangeListener
+            mA11yServicesStateChangeListener = manager -> onTargetFeaturesChanged();
     private final Handler mHandler = new Handler(Looper.getMainLooper());
     private final OnSettingsContentsChanged mSettingsContentsCallback;
     private final SecureSettings mSecureSettings;
@@ -142,9 +147,10 @@
         }
     };
 
-    MenuInfoRepository(Context context,
+    MenuInfoRepository(Context context, AccessibilityManager accessibilityManager,
             OnSettingsContentsChanged settingsContentsChanged, SecureSettings secureSettings) {
         mContext = context;
+        mAccessibilityManager = accessibilityManager;
         mConfiguration = new Configuration(context.getResources().getConfiguration());
         mSettingsContentsCallback = settingsContentsChanged;
         mSecureSettings = secureSettings;
@@ -238,6 +244,13 @@
                 mSecureSettings.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS),
                 /* notifyForDescendants */ false, mMenuTargetFeaturesContentObserver,
                 UserHandle.USER_CURRENT);
+        if (!com.android.systemui.Flags.floatingMenuNarrowTargetContentObserver()) {
+            mSecureSettings.registerContentObserverForUserSync(
+                    mSecureSettings.getUriFor(ENABLED_ACCESSIBILITY_SERVICES),
+                    /* notifyForDescendants */ false,
+                    mMenuTargetFeaturesContentObserver,
+                    UserHandle.USER_CURRENT);
+        }
         mSecureSettings.registerContentObserverForUserSync(
                 mSecureSettings.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE),
                 /* notifyForDescendants */ false, mMenuSizeContentObserver,
@@ -251,6 +264,11 @@
                 /* notifyForDescendants */ false, mMenuFadeOutContentObserver,
                 UserHandle.USER_CURRENT);
         mContext.registerComponentCallbacks(mComponentCallbacks);
+
+        if (!com.android.systemui.Flags.floatingMenuNarrowTargetContentObserver()) {
+            mAccessibilityManager.addAccessibilityServicesStateChangeListener(
+                    mA11yServicesStateChangeListener);
+        }
     }
 
     void unregisterObserversAndCallbacks() {
@@ -258,6 +276,11 @@
         mContext.getContentResolver().unregisterContentObserver(mMenuSizeContentObserver);
         mContext.getContentResolver().unregisterContentObserver(mMenuFadeOutContentObserver);
         mContext.unregisterComponentCallbacks(mComponentCallbacks);
+
+        if (!com.android.systemui.Flags.floatingMenuNarrowTargetContentObserver()) {
+            mAccessibilityManager.removeAccessibilityServicesStateChangeListener(
+                    mA11yServicesStateChangeListener);
+        }
     }
 
     interface OnSettingsContentsChanged {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java
index cfcaa4f..cb96e78 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java
@@ -42,7 +42,8 @@
             NavigationModeController navigationModeController) {
         mWindowManager = viewCaptureAwareWindowManager;
 
-        MenuViewModel menuViewModel = new MenuViewModel(context, secureSettings);
+        MenuViewModel menuViewModel = new MenuViewModel(
+                context, accessibilityManager, secureSettings);
         MenuViewAppearance menuViewAppearance = new MenuViewAppearance(context, windowManager);
 
         mMenuViewLayer = new MenuViewLayer(context, windowManager, accessibilityManager,
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewModel.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewModel.java
index 46c407e..f924784 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewModel.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewModel.java
@@ -17,6 +17,7 @@
 package com.android.systemui.accessibility.floatingmenu;
 
 import android.content.Context;
+import android.view.accessibility.AccessibilityManager;
 
 import androidx.lifecycle.LiveData;
 import androidx.lifecycle.MutableLiveData;
@@ -42,9 +43,10 @@
     private final MutableLiveData<Position> mPercentagePositionData = new MutableLiveData<>();
     private final MenuInfoRepository mInfoRepository;
 
-    MenuViewModel(Context context, SecureSettings secureSettings) {
-        mInfoRepository = new MenuInfoRepository(context, /* settingsContentsChanged= */ this,
-                secureSettings);
+    MenuViewModel(Context context, AccessibilityManager accessibilityManager,
+            SecureSettings secureSettings) {
+        mInfoRepository = new MenuInfoRepository(context,
+                accessibilityManager, /* settingsContentsChanged= */ this, secureSettings);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
index ad12229..56435df 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
@@ -52,7 +52,6 @@
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
-import com.android.settingslib.Utils;
 import com.android.settingslib.bluetooth.BluetoothCallback;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -472,8 +471,8 @@
         view.setContentDescription(item.getToolName());
         icon.setImageDrawable(item.getToolIcon());
         if (item.isCustomIcon()) {
-            icon.getDrawable().mutate().setTint(Utils.getColorAttr(context,
-                    com.android.internal.R.attr.materialColorOnPrimaryContainer).getDefaultColor());
+            icon.getDrawable().mutate().setTint(context.getColor(
+                    com.android.internal.R.color.materialColorOnPrimaryContainer));
         }
         text.setText(item.getToolName());
         Intent intent = item.getToolIntent();
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java
index e47e4b2..7e1d538 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java
@@ -27,7 +27,6 @@
 import androidx.annotation.NonNull;
 import androidx.recyclerview.widget.RecyclerView;
 
-import com.android.settingslib.Utils;
 import com.android.systemui.bluetooth.qsdialog.DeviceItem;
 import com.android.systemui.res.R;
 
@@ -131,10 +130,9 @@
             }
 
             // tint different color in different state for bad color contrast problem
-            int tintColor = item.isActive() ? Utils.getColorAttr(mContext,
-                    com.android.internal.R.attr.materialColorOnPrimaryContainer).getDefaultColor()
-                    : Utils.getColorAttr(mContext,
-                            com.android.internal.R.attr.materialColorOnSurface).getDefaultColor();
+            int tintColor = item.isActive() ? mContext.getColor(
+                    com.android.internal.R.color.materialColorOnPrimaryContainer)
+                    : mContext.getColor(com.android.internal.R.color.materialColorOnSurface);
 
             Pair<Drawable, String> iconPair = item.getIconWithDescription();
             if (iconPair != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesSpinnerAdapter.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesSpinnerAdapter.java
index 28d742c..fda4f03 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesSpinnerAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesSpinnerAdapter.java
@@ -64,9 +64,9 @@
 
         TextView text = view.findViewById(R.id.hearing_devices_spinner_text);
         if (text != null) {
-            int tintColor = Utils.getColorAttr(mContext,
-                    isSelected ? com.android.internal.R.attr.materialColorOnPrimaryContainer
-                            : com.android.internal.R.attr.materialColorOnSurface).getDefaultColor();
+            int tintColor = mContext.getColor(
+                    isSelected ? com.android.internal.R.color.materialColorOnPrimaryContainer
+                            : com.android.internal.R.color.materialColorOnSurface);
             text.setTextColor(tintColor);
         }
         return view;
diff --git a/packages/SystemUI/src/com/android/systemui/ambient/statusbar/ui/AmbientStatusBarView.java b/packages/SystemUI/src/com/android/systemui/ambient/statusbar/ui/AmbientStatusBarView.java
index 9e1b09c..081d2a0 100644
--- a/packages/SystemUI/src/com/android/systemui/ambient/statusbar/ui/AmbientStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/ambient/statusbar/ui/AmbientStatusBarView.java
@@ -75,8 +75,8 @@
     private ShadowInfo mAmbientShadowInfo;
     private int mDrawableSize;
     private int mDrawableInsetSize;
-    private static final float KEY_SHADOW_ALPHA = 0.35f;
-    private static final float AMBIENT_SHADOW_ALPHA = 0.4f;
+    private static final float KEY_SHADOW_ALPHA = 0.8f;
+    private static final float AMBIENT_SHADOW_ALPHA = 0.6f;
 
     public AmbientStatusBarView(Context context) {
         this(context, null);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 316849d..d0cb507 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -714,12 +714,12 @@
         onDialogDismissed(reason);
     }
     @Inject
-    public AuthController(Context context,
+    public AuthController(@Main Context context,
             @Application CoroutineScope applicationCoroutineScope,
             Execution execution,
             CommandQueue commandQueue,
             ActivityTaskManager activityTaskManager,
-            @NonNull WindowManager windowManager,
+            @NonNull @Main WindowManager windowManager,
             @Nullable FingerprintManager fingerprintManager,
             @Nullable FaceManager faceManager,
             Optional<AuthContextPlugins> contextPlugins,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
index f6cc724..22d2aaf 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
@@ -36,6 +36,7 @@
 import com.android.systemui.biometrics.data.repository.FacePropertyRepository
 import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.deviceentry.domain.interactor.AuthRippleInteractor
 import com.android.systemui.keyguard.WakefulnessLifecycle
 import com.android.systemui.keyguard.shared.model.BiometricUnlockSource
@@ -69,9 +70,9 @@
 class AuthRippleController
 @Inject
 constructor(
-    private val sysuiContext: Context,
+    @Main private val sysuiContext: Context,
     private val authController: AuthController,
-    private val configurationController: ConfigurationController,
+    @Main private val configurationController: ConfigurationController,
     private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
     private val keyguardStateController: KeyguardStateController,
     private val wakefulnessLifecycle: WakefulnessLifecycle,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationBroadcastReceiver.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationBroadcastReceiver.java
index 027f674..8376850 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationBroadcastReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationBroadcastReceiver.java
@@ -22,6 +22,7 @@
 import android.hardware.biometrics.BiometricSourceType;
 
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
 
 import javax.inject.Inject;
 
@@ -43,7 +44,7 @@
     private final BiometricNotificationDialogFactory mNotificationDialogFactory;
     @Inject
     BiometricNotificationBroadcastReceiver(
-            Context context,
+            @Main Context context,
             BiometricNotificationDialogFactory notificationDialogFactory) {
         mContext = context;
         mNotificationDialogFactory = notificationDialogFactory;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java
index 3b49ce2..e5c2267 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java
@@ -45,6 +45,7 @@
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.systemui.CoreStartable;
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.res.R;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
@@ -145,7 +146,7 @@
     };
 
     @Inject
-    public BiometricNotificationService(@NonNull Context context,
+    public BiometricNotificationService(@NonNull @Main Context context,
             @NonNull KeyguardUpdateMonitor keyguardUpdateMonitor,
             @NonNull KeyguardStateController keyguardStateController,
             @NonNull Handler handler, @NonNull NotificationManager notificationManager,
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 178e111..d9ed9ca 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
@@ -24,7 +24,7 @@
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.shade.ShadeDisplayAware
+import com.android.systemui.dagger.qualifiers.Main
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
@@ -43,7 +43,7 @@
     @Application private val applicationScope: CoroutineScope,
     @Application private val context: Context,
     repository: FingerprintPropertyRepository,
-    @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
+    @Main configurationInteractor: ConfigurationInteractor,
     displayStateInteractor: DisplayStateInteractor,
     udfpsOverlayInteractor: UdfpsOverlayInteractor,
 ) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/SideFpsSensorInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/SideFpsSensorInteractor.kt
index c3dc2d4..52e8557 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/SideFpsSensorInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/SideFpsSensorInteractor.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.biometrics.shared.model.FingerprintSensorType
 import com.android.systemui.biometrics.shared.model.isDefaultOrientation
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -48,9 +49,9 @@
 class SideFpsSensorInteractor
 @Inject
 constructor(
-    private val context: Context,
+    @Main private val context: Context,
     fingerprintPropertyRepository: FingerprintPropertyRepository,
-    windowManager: WindowManager,
+    @Main windowManager: WindowManager,
     displayStateInteractor: DisplayStateInteractor,
     fingerprintInteractiveToAuthProvider: Optional<FingerprintInteractiveToAuthProvider>,
     biometricSettingsRepository: BiometricSettingsRepository,
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 0ad83ec..38b1d7d 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
@@ -37,7 +37,6 @@
 import android.widget.LinearLayout
 import android.widget.Space
 import android.widget.TextView
-import com.android.settingslib.Utils
 import com.android.systemui.biometrics.Utils.ellipsize
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.res.R
@@ -294,7 +293,7 @@
     resources.getDimensionPixelSize(R.dimen.biometric_prompt_content_list_item_bullet_gap_width)
 
 private fun getListItemBulletColor(context: Context): Int =
-    Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.materialColorOnSurface)
+    context.getColor(com.android.internal.R.color.materialColorOnSurface)
 
 private fun <T : View> T.width(function: (Int) -> Unit) {
     if (width == 0)
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 df34952..4dcf268 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
@@ -982,8 +982,9 @@
     activityTaskManager: ActivityTaskManager,
 ): Pair<Drawable?, String> {
     // If the app sets customized icon/description, use the passed-in value directly
-    var icon: Drawable? =
-        if (prompt.logoBitmap != null) BitmapDrawable(resources, prompt.logoBitmap) else null
+    val customizedIcon: Drawable? =
+        prompt.logoBitmap?.let { BitmapDrawable(resources, prompt.logoBitmap) }
+    var icon = customizedIcon
     var label = prompt.logoDescription ?: ""
     if (icon != null && label.isNotEmpty()) {
         return Pair(icon, label)
@@ -1009,12 +1010,11 @@
         }
     }
 
-    // Add user badge
+    // Add user badge for non-customized logo icon
     val userHandle = UserHandle.of(prompt.userInfo.userId)
-    if (label.isNotEmpty()) {
-        label = packageManager.getUserBadgedLabel(label, userHandle).toString()
+    if (icon != null && icon != customizedIcon) {
+        icon = packageManager.getUserBadgedIcon(icon, userHandle)
     }
-    icon = icon?.let { packageManager.getUserBadgedIcon(it, userHandle) }
 
     return Pair(icon, label)
 }
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 c2a4ee3..5557161 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
@@ -164,21 +164,12 @@
             showIndicatorForDeviceEntry: Boolean ->
             val callbacks = mutableListOf<LottieCallback>()
             if (showIndicatorForDeviceEntry) {
-                val indicatorColor =
-                    com.android.settingslib.Utils.getColorAttrDefaultColor(
-                        applicationContext,
-                        com.android.internal.R.attr.materialColorPrimaryFixed
-                    )
-                val outerRimColor =
-                    com.android.settingslib.Utils.getColorAttrDefaultColor(
-                        applicationContext,
-                        com.android.internal.R.attr.materialColorPrimaryFixedDim
-                    )
-                val chevronFill =
-                    com.android.settingslib.Utils.getColorAttrDefaultColor(
-                        applicationContext,
-                        com.android.internal.R.attr.materialColorOnPrimaryFixed
-                    )
+                val indicatorColor = applicationContext.getColor(
+                        com.android.internal.R.color.materialColorPrimaryFixed)
+                val outerRimColor = applicationContext.getColor(
+                        com.android.internal.R.color.materialColorPrimaryFixedDim)
+                val chevronFill = applicationContext.getColor(
+                        com.android.internal.R.color.materialColorOnPrimaryFixed)
                 callbacks.add(LottieCallback(KeyPath(".blue600", "**"), indicatorColor))
                 callbacks.add(LottieCallback(KeyPath(".blue400", "**"), outerRimColor))
                 callbacks.add(LottieCallback(KeyPath(".black", "**"), chevronFill))
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt
index d7a0fc9..9cfb5be 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt
@@ -405,13 +405,10 @@
                     }
 
                     // updating icon colors
-                    val tintColor =
-                        com.android.settingslib.Utils.getColorAttr(
-                                context,
-                                if (item.isActive) InternalR.attr.materialColorOnPrimaryContainer
-                                else InternalR.attr.materialColorOnSurface,
-                            )
-                            .defaultColor
+                    val tintColor = context.getColor(
+                        if (item.isActive) InternalR.color.materialColorOnPrimaryContainer
+                        else InternalR.color.materialColorOnSurface
+                    )
 
                     // update icons
                     iconView.apply {
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/EmergencyServicesRepository.kt b/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/EmergencyServicesRepository.kt
index a42ae03..cdd1b3c 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/EmergencyServicesRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/EmergencyServicesRepository.kt
@@ -18,7 +18,6 @@
 
 import android.content.res.Resources
 import com.android.internal.R
-import com.android.systemui.common.ui.GlobalConfig
 import com.android.systemui.common.ui.data.repository.ConfigurationRepository
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
@@ -37,7 +36,7 @@
 constructor(
     @Application private val applicationScope: CoroutineScope,
     @Main private val resources: Resources,
-    @GlobalConfig configurationRepository: ConfigurationRepository,
+    @Main configurationRepository: ConfigurationRepository,
 ) {
     /**
      * Whether to enable emergency services calls while the SIM card is locked. This is disabled in
@@ -49,7 +48,7 @@
             .stateIn(
                 scope = applicationScope,
                 started = SharingStarted.Eagerly,
-                initialValue = getEnableEmergencyCallWhileSimLocked()
+                initialValue = getEnableEmergencyCallWhileSimLocked(),
             )
 
     private fun getEnableEmergencyCallWhileSimLocked(): Boolean {
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/shared/constants/KeyguardBouncerConstants.kt b/packages/SystemUI/src/com/android/systemui/bouncer/shared/constants/KeyguardBouncerConstants.kt
index 9f17811..a286d16 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/shared/constants/KeyguardBouncerConstants.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/shared/constants/KeyguardBouncerConstants.kt
@@ -33,13 +33,15 @@
     const val DEFAULT_PIN_LENGTH = 6
 
     object ColorId {
-        const val TITLE = com.android.internal.R.attr.materialColorOnSurface
-        const val PIN_SHAPES = com.android.internal.R.attr.materialColorOnSurfaceVariant
-        const val NUM_PAD_BACKGROUND = com.android.internal.R.attr.materialColorSurfaceContainerHigh
-        const val NUM_PAD_BACKGROUND_PRESSED = com.android.internal.R.attr.materialColorPrimaryFixed
-        const val NUM_PAD_PRESSED = com.android.internal.R.attr.materialColorOnPrimaryFixed
-        const val NUM_PAD_KEY = com.android.internal.R.attr.materialColorOnSurface
-        const val NUM_PAD_BUTTON = com.android.internal.R.attr.materialColorOnSecondaryFixed
-        const val EMERGENCY_BUTTON = com.android.internal.R.attr.materialColorTertiaryFixed
+        const val TITLE = com.android.internal.R.color.materialColorOnSurface
+        const val PIN_SHAPES = com.android.internal.R.color.materialColorOnSurfaceVariant
+        const val NUM_PAD_BACKGROUND =
+            com.android.internal.R.color.materialColorSurfaceContainerHigh
+        const val NUM_PAD_BACKGROUND_PRESSED =
+            com.android.internal.R.color.materialColorPrimaryFixed
+        const val NUM_PAD_PRESSED = com.android.internal.R.color.materialColorOnPrimaryFixed
+        const val NUM_PAD_KEY = com.android.internal.R.color.materialColorOnSurface
+        const val NUM_PAD_BUTTON = com.android.internal.R.color.materialColorOnSecondaryFixed
+        const val EMERGENCY_BUTTON = com.android.internal.R.color.materialColorTertiaryFixed
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
index b2d02ed..a31e61f 100644
--- a/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
@@ -107,6 +107,7 @@
                 activityOptions.setDisallowEnterPictureInPictureWhileLaunching(true)
                 activityOptions.rotationAnimationHint =
                     WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS
+                intent.collectExtraIntentKeys()
                 try {
                     activityTaskManager.startActivityAsUser(
                         null,
diff --git a/packages/SystemUI/src/com/android/systemui/common/shared/model/Color.kt b/packages/SystemUI/src/com/android/systemui/common/shared/model/Color.kt
index d235c95..d53a737 100644
--- a/packages/SystemUI/src/com/android/systemui/common/shared/model/Color.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/shared/model/Color.kt
@@ -18,6 +18,7 @@
 
 import android.annotation.AttrRes
 import android.annotation.ColorInt
+import android.annotation.ColorRes
 
 /**
  * Models a color that can be either a specific [Color.Loaded] value or a resolvable theme
@@ -28,4 +29,6 @@
     data class Loaded(@ColorInt val color: Int) : Color
 
     data class Attribute(@AttrRes val attribute: Int) : Color
+
+    data class Resource(@ColorRes val colorRes: Int) : Color
 }
diff --git a/packages/SystemUI/src/com/android/systemui/common/shared/model/TintedIcon.kt b/packages/SystemUI/src/com/android/systemui/common/shared/model/TintedIcon.kt
index 0869351..6a6c3eb 100644
--- a/packages/SystemUI/src/com/android/systemui/common/shared/model/TintedIcon.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/shared/model/TintedIcon.kt
@@ -16,10 +16,10 @@
 
 package com.android.systemui.common.shared.model
 
-import androidx.annotation.AttrRes
+import androidx.annotation.ColorRes
 
 /** Models an icon with a specific tint. */
 data class TintedIcon(
     val icon: Icon,
-    @AttrRes val tint: Int?,
+    @ColorRes val tint: Int?,
 )
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationModule.kt b/packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationModule.kt
index 7f50e4a..ad504d5 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationModule.kt
@@ -21,21 +21,11 @@
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractorImpl
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.statusbar.policy.ConfigurationController
 import dagger.Binds
 import dagger.Module
 import dagger.Provides
-import javax.inject.Qualifier
-
-/**
- * Annotates elements that provide information from the global configuration.
- *
- * The global configuration is the one associated with the main display. Secondary displays will
- * apply override to the global configuration. Elements annotated with this shouldn't be used for
- * secondary displays.
- */
-@Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class GlobalConfig
 
 @Module
 interface ConfigurationModule {
@@ -45,32 +35,32 @@
      * now, without annotation the global config associated state is provided.
      */
     @Binds
-    @Deprecated("Use the @GlobalConfig annotated one instead of this.")
+    @Deprecated("Use the @Main annotated one instead of this.")
     fun provideGlobalConfigurationState(
-        @GlobalConfig configurationState: ConfigurationState
+        @Main configurationState: ConfigurationState
     ): ConfigurationState
 
     @Binds
-    @Deprecated("Use the @GlobalConfig annotated one instead of this.")
+    @Deprecated("Use the @Main annotated one instead of this.")
     fun provideDefaultConfigurationState(
-        @GlobalConfig configurationState: ConfigurationInteractor
+        @Main configurationState: ConfigurationInteractor
     ): ConfigurationInteractor
 
     companion object {
         @SysUISingleton
         @Provides
-        @GlobalConfig
+        @Main
         fun provideGlobalConfigurationState(
             configStateFactory: ConfigurationStateImpl.Factory,
             configurationController: ConfigurationController,
-            @Application context: Context,
+            @Main context: Context,
         ): ConfigurationState {
             return configStateFactory.create(context, configurationController)
         }
 
         @SysUISingleton
         @Provides
-        @GlobalConfig
+        @Main
         fun provideGlobalConfigurationInteractor(
             configurationRepository: ConfigurationRepository
         ): ConfigurationInteractor {
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/data/repository/ConfigurationRepository.kt b/packages/SystemUI/src/com/android/systemui/common/ui/data/repository/ConfigurationRepository.kt
index df89152..4d804d0 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/data/repository/ConfigurationRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/data/repository/ConfigurationRepository.kt
@@ -23,9 +23,9 @@
 import androidx.annotation.DimenRes
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
-import com.android.systemui.common.ui.GlobalConfig
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.wrapper.DisplayUtilsWrapper
 import dagger.Binds
@@ -162,19 +162,19 @@
      * injected.
      */
     @Binds
-    @Deprecated("Use the ConfigurationRepository annotated with @GlobalConfig instead.")
+    @Deprecated("Use the ConfigurationRepository annotated with @Main instead.")
     @SysUISingleton
     abstract fun provideDefaultConfigRepository(
-        @GlobalConfig configurationRepository: ConfigurationRepository
+        @Main configurationRepository: ConfigurationRepository
     ): ConfigurationRepository
 
     companion object {
         @Provides
-        @GlobalConfig
+        @Main
         @SysUISingleton
         fun provideGlobalConfigRepository(
             context: Context,
-            @GlobalConfig configurationController: ConfigurationController,
+            @Main configurationController: ConfigurationController,
             factory: ConfigurationRepositoryImpl.Factory,
         ): ConfigurationRepository {
             return factory.create(context, configurationController)
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 f9b30c6..ea42869 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
@@ -27,6 +27,7 @@
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.compose.animation.scene.SceneKey
 import com.android.compose.animation.scene.TransitionKey
+import com.android.systemui.Flags.communalResponsiveGrid
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.communal.data.repository.CommunalMediaRepository
 import com.android.systemui.communal.data.repository.CommunalSmartspaceRepository
@@ -535,7 +536,9 @@
                 // Order by creation time descending.
                 ongoingContent.sortByDescending { it.createdTimestampMillis }
                 // Resize the items.
-                ongoingContent.resizeItems()
+                if (!communalResponsiveGrid()) {
+                    ongoingContent.resizeItems()
+                }
 
                 // Return the sorted and resized items.
                 ongoingContent
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt
index da613f5..c0456d5 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt
@@ -110,6 +110,11 @@
             get() = fixedHalfOrResponsiveSize()
     }
 
+    /** An empty spacer to reserve space in the grid. */
+    data class Spacer(override val size: CommunalContentSize) : CommunalContentModel {
+        override val key: String = KEY.spacer()
+    }
+
     /** A CTA tile in the glanceable hub view mode which can be dismissed. */
     class CtaTileInViewMode : CommunalContentModel {
         override val key: String = KEY.CTA_TILE_IN_VIEW_MODE_KEY
@@ -171,6 +176,10 @@
             fun umo(): String {
                 return "umo"
             }
+
+            fun spacer(): String {
+                return "spacer_${UUID.randomUUID()}"
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModel.kt
new file mode 100644
index 0000000..7d5b196
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModel.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.systemui.communal.ui.viewmodel
+
+import android.annotation.SuppressLint
+import android.app.DreamManager
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.statusbar.policy.BatteryController
+import com.android.systemui.util.kotlin.isDevicePluggedIn
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.receiveAsFlow
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+class CommunalToDreamButtonViewModel
+@AssistedInject
+constructor(
+    @Background private val backgroundContext: CoroutineContext,
+    batteryController: BatteryController,
+    private val dreamManager: DreamManager,
+) : ExclusiveActivatable() {
+
+    private val _requests = Channel<Unit>(Channel.BUFFERED)
+
+    /** Whether we should show a button on hub to switch to dream. */
+    @SuppressLint("MissingPermission")
+    val shouldShowDreamButtonOnHub =
+        batteryController
+            .isDevicePluggedIn()
+            .distinctUntilChanged()
+            .map { isPluggedIn -> isPluggedIn && dreamManager.canStartDreaming(true) }
+            .flowOn(backgroundContext)
+
+    /** Handle a tap on the "show dream" button. */
+    fun onShowDreamButtonTap() {
+        _requests.trySend(Unit)
+    }
+
+    @SuppressLint("MissingPermission")
+    override suspend fun onActivated(): Nothing = coroutineScope {
+        launch {
+            _requests.receiveAsFlow().collectLatest {
+                withContext(backgroundContext) { dreamManager.startDream() }
+            }
+        }
+
+        awaitCancellation()
+    }
+
+    @AssistedFactory
+    interface Factory {
+        fun create(): CommunalToDreamButtonViewModel
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
index eb7420f..83bd265 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
@@ -22,6 +22,7 @@
 import android.view.View
 import android.view.accessibility.AccessibilityNodeInfo
 import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.systemui.Flags
 import com.android.systemui.communal.domain.interactor.CommunalInteractor
 import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
 import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
@@ -293,6 +294,10 @@
     }
 
     override fun onLongClick() {
+        if (Flags.glanceableHubDirectEditMode()) {
+            onOpenWidgetEditor(false)
+            return
+        }
         setCurrentPopupType(PopupType.CustomizeWidgetButton)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt b/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt
index 4217744..481acc9 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt
@@ -18,7 +18,6 @@
 
 import android.content.Context
 import android.graphics.Color
-import com.android.settingslib.Utils
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
@@ -54,9 +53,6 @@
 
     private fun loadBackgroundColor(): Color =
         Color.valueOf(
-            Utils.getColorAttrDefaultColor(
-                context,
-                com.android.internal.R.attr.materialColorPrimary
-            )
+            context.getColor(com.android.internal.R.color.materialColorPrimary)
         )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/util/ResizeUtils.kt b/packages/SystemUI/src/com/android/systemui/communal/util/ResizeUtils.kt
new file mode 100644
index 0000000..36cc1c0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/util/ResizeUtils.kt
@@ -0,0 +1,71 @@
+/*
+ * 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.util
+
+import com.android.systemui.communal.domain.model.CommunalContentModel
+import com.android.systemui.communal.shared.model.CommunalContentSize
+
+object ResizeUtils {
+    /**
+     * Resizes ongoing items such that we don't mix regular content with ongoing content.
+     *
+     * NOTE: This is *NOT* a pure function, as it modifies items in the input list.
+     *
+     * Assumptions:
+     * 1. Ongoing content is always at the start of the list.
+     * 2. The maximum size of ongoing content is 2 rows.
+     */
+    fun resizeOngoingItems(
+        list: List<CommunalContentModel>,
+        numRows: Int,
+    ): List<CommunalContentModel> {
+        val finalizedList = mutableListOf<CommunalContentModel>()
+        val numOngoing = list.count { it is CommunalContentModel.Ongoing }
+        // Calculate the number of extra rows we have if each ongoing item were to take up a single
+        // row. This is the number of rows we have to distribute across items.
+        var extraRows =
+            if (numOngoing % numRows == 0) {
+                0
+            } else {
+                numRows - (numOngoing % numRows)
+            }
+        var remainingRows = numRows
+
+        for (item in list) {
+            if (item is CommunalContentModel.Ongoing) {
+                if (remainingRows == 0) {
+                    // Start a new column.
+                    remainingRows = numRows
+                }
+                val newSize = if (extraRows > 0 && remainingRows > 1) 2 else 1
+                item.size = CommunalContentSize.Responsive(newSize)
+                finalizedList.add(item)
+                extraRows -= (newSize - 1)
+                remainingRows -= newSize
+            } else {
+                if (numOngoing > 0 && remainingRows > 0) {
+                    finalizedList.add(
+                        CommunalContentModel.Spacer(CommunalContentSize.Responsive(remainingRows))
+                    )
+                }
+                remainingRows = -1
+                finalizedList.add(item)
+            }
+        }
+        return finalizedList
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
index 78a8a42..9ae106c 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
@@ -708,6 +708,14 @@
         return context.getSystemService(WindowManager.class);
     }
 
+    /** A window manager working for the default display only. */
+    @Provides
+    @Singleton
+    @Main
+    static WindowManager provideMainWindowManager(WindowManager windowManager) {
+        return windowManager;
+    }
+
     @Provides
     @Singleton
     static ViewCaptureAwareWindowManager provideViewCaptureAwareWindowManager(
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java b/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
index 3072f74..ddc88a8 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
@@ -21,6 +21,7 @@
 import android.view.Display;
 
 import com.android.systemui.dagger.qualifiers.Application;
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.PluginsModule;
 import com.android.systemui.unfold.UnfoldTransitionModule;
 import com.android.systemui.util.concurrency.GlobalConcurrencyModule;
@@ -62,6 +63,13 @@
         return context.getApplicationContext();
     }
 
+    /** Provides the default content with the main annotation. */
+    @Provides
+    @Main
+    public Context provideMainContext(Context context) {
+        return context;
+    }
+
     /**
      * @deprecated Deprecdated because {@link Display#getMetrics} is deprecated.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index 580896c..00eead6 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -21,7 +21,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.InitController;
 import com.android.systemui.SystemUIAppComponentFactoryBase;
-import com.android.systemui.common.ui.GlobalConfig;
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dagger.qualifiers.PerUser;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.KeyguardSliceProvider;
@@ -128,14 +128,14 @@
      * Creates a ConfigurationController.
      */
     @SysUISingleton
-    @GlobalConfig
+    @Main
     ConfigurationController getConfigurationController();
 
     /**
      * Creates a ConfigurationForwarder.
      */
     @SysUISingleton
-    @GlobalConfig
+    @Main
     ConfigurationForwarder getConfigurationForwarder();
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
index 1e9be09..246f657 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
@@ -17,7 +17,6 @@
 
 package com.android.systemui.keyboard.backlight.ui.view
 
-import android.annotation.AttrRes
 import android.annotation.ColorInt
 import android.app.Dialog
 import android.content.Context
@@ -38,7 +37,6 @@
 import android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
 import androidx.annotation.IdRes
 import androidx.core.view.setPadding
-import com.android.settingslib.Utils
 import com.android.systemui.res.R
 
 class KeyboardBacklightDialog(
@@ -80,25 +78,25 @@
 
     @ColorInt
     private val filledRectangleColor =
-        getColorFromStyle(com.android.internal.R.attr.materialColorPrimary)
+        context.getColor(com.android.internal.R.color.materialColorPrimary)
     @ColorInt
     private val emptyRectangleColor =
-        getColorFromStyle(com.android.internal.R.attr.materialColorOutlineVariant)
+        context.getColor(com.android.internal.R.color.materialColorOutlineVariant)
     @ColorInt
     private val backgroundColor =
-        getColorFromStyle(com.android.internal.R.attr.materialColorSurfaceBright)
+        context.getColor(com.android.internal.R.color.materialColorSurfaceBright)
     @ColorInt
     private val defaultIconColor =
-        getColorFromStyle(com.android.internal.R.attr.materialColorOnPrimary)
+        context.getColor(com.android.internal.R.color.materialColorOnPrimary)
     @ColorInt
     private val defaultIconBackgroundColor =
-        getColorFromStyle(com.android.internal.R.attr.materialColorPrimary)
+        context.getColor(com.android.internal.R.color.materialColorPrimary)
     @ColorInt
     private val dimmedIconColor =
-        getColorFromStyle(com.android.internal.R.attr.materialColorOnSurface)
+        context.getColor(com.android.internal.R.color.materialColorOnSurface)
     @ColorInt
     private val dimmedIconBackgroundColor =
-        getColorFromStyle(com.android.internal.R.attr.materialColorSurfaceDim)
+        context.getColor(com.android.internal.R.color.materialColorSurfaceDim)
 
     private val levelContentDescription = context.getString(R.string.keyboard_backlight_value)
 
@@ -153,11 +151,6 @@
         }
     }
 
-    @ColorInt
-    fun getColorFromStyle(@AttrRes colorId: Int): Int {
-        return Utils.getColorAttrDefaultColor(context, colorId)
-    }
-
     fun updateState(current: Int, max: Int, forceRefresh: Boolean = false) {
         if (maxLevel != max || forceRefresh) {
             maxLevel = max
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModel.kt
index 84a423e..c3e6f0c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModel.kt
@@ -21,11 +21,10 @@
 import android.view.WindowManager
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.settingslib.Utils
-import com.android.systemui.common.ui.GlobalConfig
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
 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.Main
 import com.android.systemui.keyboard.docking.domain.interactor.KeyboardDockingIndicationInteractor
 import com.android.systemui.surfaceeffects.glowboxeffect.GlowBoxConfig
 import javax.inject.Inject
@@ -37,10 +36,10 @@
 class KeyboardDockingIndicationViewModel
 @Inject
 constructor(
-    private val windowManager: WindowManager,
-    @Application private val context: Context,
+    @Main private val windowManager: WindowManager,
+    @Main private val context: Context,
     keyboardDockingIndicationInteractor: KeyboardDockingIndicationInteractor,
-    @GlobalConfig configurationInteractor: ConfigurationInteractor,
+    @Main configurationInteractor: ConfigurationInteractor,
     @Background private val backgroundScope: CoroutineScope,
 ) {
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/OWNERS b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/OWNERS
new file mode 100644
index 0000000..2355c48
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 1562219
+chrisgollner@google.com
+jmokut@google.com
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt
index 30a2f33..d7be5e6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt
@@ -136,10 +136,6 @@
             KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_LEFT to R.string.system_multitasking_lhs,
             KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_RIGHT to R.string.system_multitasking_rhs,
             KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION to R.string.system_multitasking_full_screen,
-            KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_LEFT to
-                R.string.system_multitasking_splitscreen_focus_lhs,
-            KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_RIGHT to
-                R.string.system_multitasking_splitscreen_focus_rhs,
         )
 
     val shortcutLabelToKeyGestureTypeMap: Map<String, Int>
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
index df6b04e..d785b5b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
@@ -26,7 +26,6 @@
 import android.view.KeyEvent.KEYCODE_LEFT_BRACKET
 import android.view.KeyEvent.KEYCODE_MINUS
 import android.view.KeyEvent.KEYCODE_RIGHT_BRACKET
-import android.view.KeyEvent.META_ALT_ON
 import android.view.KeyEvent.META_CTRL_ON
 import android.view.KeyEvent.META_META_ON
 import android.view.KeyboardShortcutGroup
@@ -74,20 +73,6 @@
                 command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_UP)
             }
         )
-        //  Change split screen focus to RHS:
-        //   - Meta + Alt + Right arrow
-        add(
-            shortcutInfo(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
-                command(META_META_ON or META_ALT_ON, KEYCODE_DPAD_RIGHT)
-            }
-        )
-        //  Change split screen focus to LHS:
-        //   - Meta + Alt + Left arrow
-        add(
-            shortcutInfo(resources.getString(R.string.system_multitasking_splitscreen_focus_lhs)) {
-                command(META_META_ON or META_ALT_ON, KEYCODE_DPAD_LEFT)
-            }
-        )
         if (enableMoveToNextDisplayShortcut()) {
             // Move a window to the next display:
             //  - Meta + Ctrl + D
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
index 2724918..af6f0cb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
@@ -615,7 +615,7 @@
             }
             .focusable(interactionSource = interactionSource)
             .padding(8.dp)
-            .semantics { contentDescription = shortcut.contentDescription }
+            .semantics(mergeDescendants = true) { contentDescription = shortcut.contentDescription }
     ) {
         Row(
             modifier =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt
index 0cb8dd4..5c03d65 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt
@@ -36,7 +36,6 @@
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.mapNotNull
 
 /**
@@ -51,17 +50,11 @@
     private val logger: KeyguardTransitionAnimationLogger,
 ) {
     /** Invoke once per transition between FROM->TO states to get access to a shared flow. */
-    fun setup(
-        duration: Duration,
-        edge: Edge,
-    ): FlowBuilder {
+    fun setup(duration: Duration, edge: Edge): FlowBuilder {
         return FlowBuilder(duration, edge)
     }
 
-    inner class FlowBuilder(
-        private val transitionDuration: Duration,
-        private val edge: Edge,
-    ) {
+    inner class FlowBuilder(private val transitionDuration: Duration, private val edge: Edge) {
         fun setupWithoutSceneContainer(edge: Edge.StateToState): FlowBuilder {
             if (SceneContainerFlag.isEnabled) return this
             return setup(this.transitionDuration, edge)
@@ -72,6 +65,8 @@
          * in the range of [0, 1]. View animations should begin and end within a subset of this
          * range. This function maps the [startTime] and [duration] into [0, 1], when this subset is
          * valid.
+         *
+         * Note that [onCancel] isn't used when the scene framework is enabled.
          */
         fun sharedFlow(
             duration: Duration,
@@ -81,7 +76,7 @@
             onCancel: (() -> Float)? = null,
             onFinish: (() -> Float)? = null,
             interpolator: Interpolator = LINEAR,
-            name: String? = null
+            name: String? = null,
         ): Flow<Float> {
             return sharedFlowWithState(
                     duration = duration,
@@ -113,7 +108,7 @@
             onCancel: (() -> Float)? = null,
             onFinish: (() -> Float)? = null,
             interpolator: Interpolator = LINEAR,
-            name: String? = null
+            name: String? = null,
         ): Flow<StateToValue> {
             if (!duration.isPositive()) {
                 throw IllegalArgumentException("duration must be a positive number: $duration")
@@ -155,20 +150,40 @@
 
             return transitionInteractor
                 .transition(edge)
-                .map { step ->
-                    StateToValue(
-                            from = step.from,
-                            to = step.to,
-                            transitionState = step.transitionState,
-                            value =
-                                when (step.transitionState) {
-                                    STARTED -> stepToValue(step)
-                                    RUNNING -> stepToValue(step)
-                                    CANCELED -> onCancel?.invoke()
-                                    FINISHED -> onFinish?.invoke()
-                                }
-                        )
-                        .also { logger.logTransitionStep(name, step, it.value) }
+                .mapNotNull { step ->
+                    if (SceneContainerFlag.isEnabled && step.transitionState == CANCELED) {
+                        // When the scene framework is enabled, there's no need to emit an alpha
+                        // value when the keyguard transition animation is canceled because there's
+                        // always going to be a new, reversed keyguard transition animation back to
+                        // the original KeyguardState that starts right when this one was canceled.
+                        //
+                        // For example, if swiping up slightly on the Lockscreen scene and then
+                        // releasing before the transition to the Bouncer scene is committed, the
+                        // KTF transition of LOCKSCREEN -> PRIMARY_BOUNCER received a CANCELED and
+                        // the scene framework immediately starts a reversed transition of
+                        // PRIMARY_BOUNCER -> LOCKSCREEN, which picks up where the previous one left
+                        // off.
+                        //
+                        // If it were allowed for the CANCELED from the original KTF transition to
+                        // emit a value, a race condition could form where the value from CANCELED
+                        // arrives downstream _after_ the reversed transition is finished, causing
+                        // the transition to end up in an incorrect state at rest.
+                        null
+                    } else {
+                        StateToValue(
+                                from = step.from,
+                                to = step.to,
+                                transitionState = step.transitionState,
+                                value =
+                                    when (step.transitionState) {
+                                        STARTED -> stepToValue(step)
+                                        RUNNING -> stepToValue(step)
+                                        CANCELED -> onCancel?.invoke()
+                                        FINISHED -> onFinish?.invoke()
+                                    },
+                            )
+                            .also { logger.logTransitionStep(name, step, it.value) }
+                    }
                 }
                 .distinctUntilChanged()
         }
@@ -181,7 +196,7 @@
                 duration = 1.milliseconds,
                 onStep = { value },
                 onCancel = { value },
-                onFinish = { value }
+                onFinish = { value },
             )
         }
     }
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 3bdf7da..c59fe53 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
@@ -17,6 +17,7 @@
 package com.android.systemui.keyguard.ui.binder
 
 import android.annotation.SuppressLint
+import android.content.res.ColorStateList
 import android.graphics.Rect
 import android.graphics.drawable.Animatable2
 import android.util.Size
@@ -37,7 +38,6 @@
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.app.animation.Interpolators
 import com.android.app.tracing.coroutines.launchTraced as launch
-import com.android.settingslib.Utils
 import com.android.systemui.animation.ActivityTransitionAnimator
 import com.android.systemui.animation.Expandable
 import com.android.systemui.animation.view.LaunchableLinearLayout
@@ -382,25 +382,25 @@
 
         view.isActivated = viewModel.isActivated
         view.drawable.setTint(
-            Utils.getColorAttrDefaultColor(
-                view.context,
+            view.context.getColor(
                 if (viewModel.isActivated) {
-                    com.android.internal.R.attr.materialColorOnPrimaryFixed
+                    com.android.internal.R.color.materialColorOnPrimaryFixed
                 } else {
-                    com.android.internal.R.attr.materialColorOnSurface
-                },
+                    com.android.internal.R.color.materialColorOnSurface
+                }
             )
         )
 
         view.backgroundTintList =
             if (!viewModel.isSelected) {
-                Utils.getColorAttr(
-                    view.context,
-                    if (viewModel.isActivated) {
-                        com.android.internal.R.attr.materialColorPrimaryFixed
-                    } else {
-                        com.android.internal.R.attr.materialColorSurfaceContainerHigh
-                    }
+                ColorStateList.valueOf(
+                    view.context.getColor(
+                        if (viewModel.isActivated) {
+                            com.android.internal.R.color.materialColorPrimaryFixed
+                        } else {
+                            com.android.internal.R.color.materialColorSurfaceContainerHigh
+                        }
+                    )
                 )
             } else {
                 null
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 191e08b..5c8a234 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
@@ -18,6 +18,7 @@
 package com.android.systemui.keyguard.ui.binder
 
 import android.annotation.SuppressLint
+import android.content.res.ColorStateList
 import android.graphics.drawable.Animatable2
 import android.util.Size
 import android.view.View
@@ -32,7 +33,6 @@
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.keyguard.logging.KeyguardQuickAffordancesLogger
-import com.android.settingslib.Utils
 import com.android.systemui.animation.Expandable
 import com.android.systemui.animation.view.LaunchableImageView
 import com.android.systemui.common.shared.model.Icon
@@ -176,25 +176,25 @@
 
         view.isActivated = viewModel.isActivated
         view.drawable.setTint(
-            Utils.getColorAttrDefaultColor(
-                view.context,
+            view.context.getColor(
                 if (viewModel.isActivated) {
-                    com.android.internal.R.attr.materialColorOnPrimaryFixed
+                    com.android.internal.R.color.materialColorOnPrimaryFixed
                 } else {
-                    com.android.internal.R.attr.materialColorOnSurface
+                    com.android.internal.R.color.materialColorOnSurface
                 },
             )
         )
 
         view.backgroundTintList =
             if (!viewModel.isSelected) {
-                Utils.getColorAttr(
-                    view.context,
-                    if (viewModel.isActivated) {
-                        com.android.internal.R.attr.materialColorPrimaryFixed
-                    } else {
-                        com.android.internal.R.attr.materialColorSurfaceContainerHigh
-                    }
+                ColorStateList.valueOf(
+                    view.context.getColor(
+                        if (viewModel.isActivated) {
+                            com.android.internal.R.color.materialColorPrimaryFixed
+                        } else {
+                            com.android.internal.R.color.materialColorSurfaceContainerHigh
+                        }
+                    )
                 )
             } else {
                 null
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 eab7528..85725d2 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
@@ -368,8 +368,8 @@
                     SceneContainerFlag.isEnabled,
                 )
             )
-        val startPadding: Int = smartspaceViewModel.getSmartspaceStartPadding(previewContext)
-        val endPadding: Int = smartspaceViewModel.getSmartspaceEndPadding(previewContext)
+        val startPadding: Int = smartspaceViewModel.getDateWeatherStartPadding(previewContext)
+        val endPadding: Int = smartspaceViewModel.getDateWeatherEndPadding(previewContext)
 
         smartSpaceView?.let {
             it.setPaddingRelative(startPadding, topPadding, endPadding, 0)
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 d54d411..73e14b1 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
@@ -33,8 +33,8 @@
 import com.android.systemui.keyguard.ui.binder.KeyguardSmartspaceViewBinder
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel
-import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.res.R as R
+import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.shared.R as sharedR
 import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController
 import dagger.Lazy
@@ -113,8 +113,9 @@
     override fun applyConstraints(constraintSet: ConstraintSet) {
         if (!MigrateClocksToBlueprint.isEnabled) return
         if (!keyguardSmartspaceViewModel.isSmartspaceEnabled) return
-        val horizontalPaddingStart = KeyguardSmartspaceViewModel.getSmartspaceStartMargin(context)
-        val horizontalPaddingEnd = KeyguardSmartspaceViewModel.getSmartspaceEndMargin(context)
+        val dateWeatherPaddingStart = KeyguardSmartspaceViewModel.getDateWeatherStartMargin(context)
+        val smartspaceHorizontalPadding =
+            KeyguardSmartspaceViewModel.getSmartspaceHorizontalMargin(context)
         constraintSet.apply {
             // migrate addDateWeatherView, addWeatherView from KeyguardClockSwitchController
             constrainHeight(sharedR.id.date_smartspace_view, ConstraintSet.WRAP_CONTENT)
@@ -124,7 +125,7 @@
                 ConstraintSet.START,
                 ConstraintSet.PARENT_ID,
                 ConstraintSet.START,
-                horizontalPaddingStart,
+                dateWeatherPaddingStart,
             )
 
             // migrate addSmartspaceView from KeyguardClockSwitchController
@@ -135,7 +136,7 @@
                 ConstraintSet.START,
                 ConstraintSet.PARENT_ID,
                 ConstraintSet.START,
-                horizontalPaddingStart,
+                smartspaceHorizontalPadding,
             )
             connect(
                 sharedR.id.bc_smartspace_view,
@@ -143,7 +144,7 @@
                 if (keyguardSmartspaceViewModel.isShadeLayoutWide.value) R.id.split_shade_guideline
                 else ConstraintSet.PARENT_ID,
                 ConstraintSet.END,
-                horizontalPaddingEnd,
+                smartspaceHorizontalPadding,
             )
 
             if (keyguardClockViewModel.hasCustomWeatherDataDisplay.value) {
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 0280d17..15b696e 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
@@ -62,12 +62,12 @@
         overrideClockSize.value = clockSize
     }
 
-    fun getSmartspaceStartPadding(context: Context): Int {
-        return KeyguardSmartspaceViewModel.getSmartspaceStartMargin(context)
+    fun getDateWeatherStartPadding(context: Context): Int {
+        return KeyguardSmartspaceViewModel.getDateWeatherStartMargin(context)
     }
 
-    fun getSmartspaceEndPadding(context: Context): Int {
-        return KeyguardSmartspaceViewModel.getSmartspaceEndMargin(context)
+    fun getDateWeatherEndPadding(context: Context): Int {
+        return KeyguardSmartspaceViewModel.getDateWeatherEndMargin(context)
     }
 
     /*
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 3266dc4..5ee80a7 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
@@ -94,14 +94,19 @@
     val isShadeLayoutWide: StateFlow<Boolean> = shadeInteractor.isShadeLayoutWide
 
     companion object {
-        fun getSmartspaceStartMargin(context: Context): Int {
+        fun getDateWeatherStartMargin(context: Context): Int {
             return context.resources.getDimensionPixelSize(R.dimen.below_clock_padding_start) +
                 context.resources.getDimensionPixelSize(customR.dimen.status_view_margin_horizontal)
         }
 
-        fun getSmartspaceEndMargin(context: Context): Int {
+        fun getDateWeatherEndMargin(context: Context): Int {
             return context.resources.getDimensionPixelSize(R.dimen.below_clock_padding_end) +
                 context.resources.getDimensionPixelSize(customR.dimen.status_view_margin_horizontal)
         }
+
+        fun getSmartspaceHorizontalMargin(context: Context): Int {
+            return context.resources.getDimensionPixelSize(R.dimen.smartspace_padding_horizontal) +
+                context.resources.getDimensionPixelSize(customR.dimen.status_view_margin_horizontal)
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt
index 2a9fe83..1e99697 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt
@@ -93,7 +93,7 @@
             scrubbing = false,
             elapsedTime = null,
             duration = 0,
-            listening = false
+            listening = false,
         )
         set(value) {
             val enabledChanged = value.enabled != field.enabled
@@ -135,7 +135,6 @@
 
             override fun onMetadataChanged(metadata: MediaMetadata?) {
                 if (!Flags.mediaControlsPostsOptimization()) return
-
                 val (enabled, duration) = getEnabledStateAndDuration(metadata)
                 if (_data.duration != duration) {
                     _data = _data.copy(enabled = enabled, duration = duration)
@@ -323,7 +322,7 @@
                     bgExecutor.executeRepeatedly(
                         this::checkPlaybackPosition,
                         0L,
-                        POSITION_UPDATE_INTERVAL_MILLIS
+                        POSITION_UPDATE_INTERVAL_MILLIS,
                     )
                 cancel = Runnable {
                     cancelPolling.run()
@@ -331,6 +330,7 @@
                 }
             }
         } else {
+            checkPlaybackPosition()
             cancel?.run()
             cancel = null
         }
@@ -542,7 +542,7 @@
             eventStart: MotionEvent?,
             event: MotionEvent,
             distanceX: Float,
-            distanceY: Float
+            distanceY: Float,
         ): Boolean {
             return shouldGoToSeekBar
         }
@@ -556,7 +556,7 @@
             eventStart: MotionEvent?,
             event: MotionEvent,
             velocityX: Float,
-            velocityY: Float
+            velocityY: Float,
         ): Boolean {
             if (Math.abs(velocityX) > flingVelocity || Math.abs(velocityY) > flingVelocity) {
                 viewModel.onSeekFalse()
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS b/packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS
index 95b8fa7..4976d94 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS
@@ -1,3 +1,3 @@
 # Bug component: 1280508
 
-# Files in this directory should still be reviewed by a member of SystemUI team
+asapperstein@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
index 2f0e129..f8d317a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
@@ -19,12 +19,12 @@
 import android.content.Context
 import android.content.pm.PackageManager
 import android.graphics.drawable.Drawable
-import androidx.annotation.AttrRes
+import androidx.annotation.ColorRes
 import androidx.annotation.DrawableRes
-import com.android.systemui.res.R
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.common.shared.model.TintedIcon
+import com.android.systemui.res.R
 import com.android.systemui.temporarydisplay.chipbar.ChipbarInfo.Companion.DEFAULT_ICON_TINT
 
 /** Utility methods for media tap-to-transfer. */
@@ -108,7 +108,7 @@
 data class IconInfo(
     val contentDescription: ContentDescription,
     val icon: MediaTttIcon,
-    @AttrRes val tint: Int?,
+    @ColorRes val tint: Int?,
     /**
      * True if [drawable] is the app's icon, and false if [drawable] is some generic default icon.
      */
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 2fda201..d33ad8f 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
@@ -122,21 +122,20 @@
         final Intent launchingIntent = getIntent();
         mReviewGrantedConsentRequired = launchingIntent.getBooleanExtra(
                 EXTRA_USER_REVIEW_GRANTED_CONSENT, false);
-        if (com.android.systemui.Flags.mediaProjectionRequestAttributionFix()) {
-            mPackageName = getLaunchedFromPackage();
-        } else {
-            mPackageName = getCallingPackage();
-        }
 
-        // This activity is launched directly by an app, or system server. System server provides
-        // the package name through the intent if so.
-        if (mPackageName == null || (
-                com.android.systemui.Flags.mediaProjectionRequestAttributionFix()
-                        && getCallingPackage() == null)) {
+        // The original requester of this activity start
+        mPackageName = getLaunchedFromPackage();
+
+        // This activity is launched directly by using startActivity(),
+        // thus getCallingPackage() will be null.
+        if (getCallingPackage() == null) {
+            // System server provides the package name through the intent if so and is able to get
+            // the result back. Other applications can't.
             if (launchingIntent.hasExtra(EXTRA_PACKAGE_REUSING_GRANTED_CONSENT)) {
                 mPackageName = launchingIntent.getStringExtra(
                         EXTRA_PACKAGE_REUSING_GRANTED_CONSENT);
             } else {
+                // The activity was not launched for result, we abort here
                 finishAsCancelled();
                 return;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
index 2d00150..138ac86 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
@@ -12,7 +12,6 @@
 import androidx.dynamicanimation.animation.SpringAnimation
 import androidx.dynamicanimation.animation.SpringForce
 import com.android.internal.util.LatencyTracker
-import com.android.settingslib.Utils
 import com.android.systemui.navigationbar.gestural.BackPanelController.DelayedOnAnimationEndListener
 
 private const val TAG = "BackPanel"
@@ -156,23 +155,21 @@
                 Configuration.UI_MODE_NIGHT_YES
 
         arrowPaint.color =
-            Utils.getColorAttrDefaultColor(
-                context,
+            context.getColor(
                 if (isDeviceInNightTheme) {
-                    com.android.internal.R.attr.materialColorOnSecondaryContainer
+                    com.android.internal.R.color.materialColorOnSecondaryContainer
                 } else {
-                    com.android.internal.R.attr.materialColorOnSecondaryFixed
-                },
+                    com.android.internal.R.color.materialColorOnSecondaryFixed
+                }
             )
 
         arrowBackgroundPaint.color =
-            Utils.getColorAttrDefaultColor(
-                context,
+            context.getColor(
                 if (isDeviceInNightTheme) {
-                    com.android.internal.R.attr.materialColorSecondaryContainer
+                    com.android.internal.R.color.materialColorSecondaryContainer
                 } else {
-                    com.android.internal.R.attr.materialColorSecondaryFixedDim
-                },
+                    com.android.internal.R.color.materialColorSecondaryFixedDim
+                }
             )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogV2.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogV2.kt
index b26ae6c..f53b6cd 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogV2.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogV2.kt
@@ -40,8 +40,8 @@
 import androidx.core.view.ViewCompat
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
 import com.android.settingslib.Utils
-import com.android.systemui.res.R
 import com.android.systemui.animation.ViewHierarchyAnimator
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.util.maybeForceFullscreen
 import java.lang.ref.WeakReference
@@ -347,16 +347,16 @@
     private fun getForegroundColor(active: Boolean) =
         Utils.getColorAttrDefaultColor(
             context,
-            if (active) com.android.internal.R.attr.materialColorOnPrimaryFixed
-            else com.android.internal.R.attr.materialColorOnSurface
+            if (active) com.android.internal.R.color.materialColorOnPrimaryFixed
+            else com.android.internal.R.color.materialColorOnSurface,
         )
 
     @ColorInt
     private fun getBackgroundColor(active: Boolean) =
         Utils.getColorAttrDefaultColor(
             context,
-            if (active) com.android.internal.R.attr.materialColorPrimaryFixed
-            else com.android.internal.R.attr.materialColorSurfaceContainerHigh
+            if (active) com.android.internal.R.color.materialColorPrimaryFixed
+            else com.android.internal.R.color.materialColorSurfaceContainerHigh,
         )
 
     private fun getMutableDrawable(@DrawableRes resId: Int) = context.getDrawable(resId)!!.mutate()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
index 5c9baa0..91a3120 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
@@ -141,6 +141,7 @@
 class FgsManagerControllerImpl
 @Inject
 constructor(
+    @ShadeDisplayAware private val context: Context,
     @ShadeDisplayAware private val resources: Resources,
     @Main private val mainExecutor: Executor,
     @Background private val backgroundExecutor: Executor,
@@ -387,7 +388,7 @@
     override fun showDialog(expandable: Expandable?) {
         synchronized(lock) {
             if (dialog == null) {
-                val dialog = systemUIDialogFactory.create()
+                val dialog = systemUIDialogFactory.create(context)
                 dialog.setTitle(R.string.fgs_manager_dialog_title)
                 dialog.setMessage(R.string.fgs_manager_dialog_message)
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
index 8d9f49e..56fece8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
@@ -33,7 +33,6 @@
 import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
 import androidx.annotation.VisibleForTesting
 import androidx.compose.animation.AnimatedContent
-import androidx.compose.animation.AnimatedVisibility
 import androidx.compose.animation.core.tween
 import androidx.compose.animation.fadeIn
 import androidx.compose.animation.fadeOut
@@ -49,6 +48,7 @@
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.offset
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.requiredHeightIn
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.runtime.Composable
@@ -77,6 +77,7 @@
 import androidx.compose.ui.semantics.CustomAccessibilityAction
 import androidx.compose.ui.semantics.customActions
 import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.round
@@ -246,51 +247,57 @@
     private fun Content() {
         PlatformTheme(isDarkTheme = true) {
             ProvideShortcutHelperIndication(interactionsConfig = interactionsConfig()) {
-                AnimatedVisibility(
-                    visible = viewModel.isQsVisibleAndAnyShadeExpanded,
-                    modifier =
-                        Modifier.graphicsLayer { alpha = viewModel.viewAlpha }
-                            // Clipping before translation to match QSContainerImpl.onDraw
-                            .offset {
-                                IntOffset(x = 0, y = viewModel.viewTranslationY.fastRoundToInt())
-                            }
-                            .thenIf(notificationScrimClippingParams.isEnabled) {
-                                Modifier.notificationScrimClip {
-                                    notificationScrimClippingParams.params
+                if (viewModel.isQsVisibleAndAnyShadeExpanded) {
+                    Box(
+                        modifier =
+                            Modifier.graphicsLayer { alpha = viewModel.viewAlpha }
+                                // Clipping before translation to match QSContainerImpl.onDraw
+                                .offset {
+                                    IntOffset(
+                                        x = 0,
+                                        y = viewModel.viewTranslationY.fastRoundToInt(),
+                                    )
                                 }
+                                .thenIf(notificationScrimClippingParams.isEnabled) {
+                                    Modifier.notificationScrimClip {
+                                        notificationScrimClippingParams.params
+                                    }
+                                }
+                                // Disable touches in the whole composable while the mirror is
+                                // showing. While the mirror is showing, an ancestor of the
+                                // ComposeView is made alpha 0, but touches are still being captured
+                                // by the composables.
+                                .gesturesDisabled(viewModel.showingMirror)
+                    ) {
+                        val isEditing by
+                            viewModel.containerViewModel.editModeViewModel.isEditing
+                                .collectAsStateWithLifecycle()
+                        val animationSpecEditMode = tween<Float>(EDIT_MODE_TIME_MILLIS)
+                        AnimatedContent(
+                            targetState = isEditing,
+                            transitionSpec = {
+                                fadeIn(animationSpecEditMode) togetherWith
+                                    fadeOut(animationSpecEditMode)
+                            },
+                            label = "EditModeAnimatedContent",
+                        ) { editing ->
+                            if (editing) {
+                                val qqsPadding = viewModel.qqsHeaderHeight
+                                EditMode(
+                                    viewModel = viewModel.containerViewModel.editModeViewModel,
+                                    modifier =
+                                        Modifier.fillMaxWidth()
+                                            .padding(top = { qqsPadding })
+                                            .padding(
+                                                horizontal = {
+                                                    QuickSettingsShade.Dimensions.Padding
+                                                        .roundToPx()
+                                                }
+                                            ),
+                                )
+                            } else {
+                                CollapsableQuickSettingsSTL()
                             }
-                            // Disable touches in the whole composable while the mirror is showing.
-                            // While the mirror is showing, an ancestor of the ComposeView is made
-                            // alpha 0, but touches are still being captured by the composables.
-                            .gesturesDisabled(viewModel.showingMirror),
-                ) {
-                    val isEditing by
-                        viewModel.containerViewModel.editModeViewModel.isEditing
-                            .collectAsStateWithLifecycle()
-                    val animationSpecEditMode = tween<Float>(EDIT_MODE_TIME_MILLIS)
-                    AnimatedContent(
-                        targetState = isEditing,
-                        transitionSpec = {
-                            fadeIn(animationSpecEditMode) togetherWith
-                                fadeOut(animationSpecEditMode)
-                        },
-                        label = "EditModeAnimatedContent",
-                    ) { editing ->
-                        if (editing) {
-                            val qqsPadding = viewModel.qqsHeaderHeight
-                            EditMode(
-                                viewModel = viewModel.containerViewModel.editModeViewModel,
-                                modifier =
-                                    Modifier.fillMaxWidth()
-                                        .padding(top = { qqsPadding })
-                                        .padding(
-                                            horizontal = {
-                                                QuickSettingsShade.Dimensions.Padding.roundToPx()
-                                            }
-                                        ),
-                            )
-                        } else {
-                            CollapsableQuickSettingsSTL()
                         }
                     }
                 }
@@ -325,9 +332,15 @@
         }
 
         SceneTransitionLayout(state = sceneState, modifier = Modifier.fillMaxSize()) {
-            scene(QuickSettings) { QuickSettingsElement() }
+            scene(QuickSettings) {
+                LaunchedEffect(Unit) { viewModel.onQSOpen() }
+                QuickSettingsElement()
+            }
 
-            scene(QuickQuickSettings) { QuickQuickSettingsElement() }
+            scene(QuickQuickSettings) {
+                LaunchedEffect(Unit) { viewModel.onQQSOpen() }
+                QuickQuickSettingsElement()
+            }
         }
     }
 
@@ -616,7 +629,14 @@
                 val Media =
                     @Composable {
                         if (viewModel.qqsMediaVisible) {
-                            MediaObject(mediaHost = viewModel.qqsMediaHost)
+                            MediaObject(
+                                // In order to have stable constraints passed to the AndroidView
+                                // during expansion (available height changing due to squishiness),
+                                // We always allow the media here to be as tall as it wants.
+                                // (b/383085298)
+                                modifier = Modifier.requiredHeightIn(max = Dp.Infinity),
+                                mediaHost = viewModel.qqsMediaHost,
+                            )
                         }
                     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
index 3c72520..07ceb64 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
@@ -28,6 +28,7 @@
 import androidx.lifecycle.LifecycleCoroutineScope
 import com.android.app.animation.Interpolators
 import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.internal.logging.UiEventLogger
 import com.android.keyguard.BouncerPanelExpansionCalculator
 import com.android.systemui.Dumpable
 import com.android.systemui.animation.ShadeInterpolation
@@ -51,6 +52,7 @@
 import com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.FooterActionsController
+import com.android.systemui.qs.QSEvent
 import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeLog
 import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeModule
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
@@ -113,6 +115,7 @@
     @Named(QUICK_QS_PANEL) val qqsMediaHost: MediaHost,
     @Named(QS_PANEL) val qsMediaHost: MediaHost,
     @Named(QSFragmentComposeModule.QS_USING_MEDIA_PLAYER) private val usingMedia: Boolean,
+    private val uiEventLogger: UiEventLogger,
     @Assisted private val lifecycleScope: LifecycleCoroutineScope,
 ) : Dumpable, ExclusiveActivatable() {
 
@@ -455,6 +458,14 @@
         falsingInteractor.isFalseTouch(Classifier.QS_SWIPE_NESTED)
     }
 
+    fun onQQSOpen() {
+        uiEventLogger.log(QSEvent.QQS_PANEL_EXPANDED)
+    }
+
+    fun onQSOpen() {
+        uiEventLogger.log(QSEvent.QS_PANEL_EXPANDED)
+    }
+
     override suspend fun onActivated(): Nothing {
         initMediaHosts() // init regardless of using media (same as current QS).
         coroutineScope {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
index 94b8a3a..1205c87 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
@@ -16,55 +16,10 @@
 
 package com.android.systemui.qs.dagger;
 
-import com.android.systemui.media.dagger.MediaModule;
-import com.android.systemui.qs.ReduceBrightColorsController;
-import com.android.systemui.qs.ReduceBrightColorsControllerImpl;
-import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeModule;
-import com.android.systemui.qs.external.QSExternalModule;
-import com.android.systemui.qs.panels.dagger.PanelsModule;
-import com.android.systemui.qs.pipeline.dagger.QSPipelineModule;
-import com.android.systemui.qs.tileimpl.QSTileImpl;
-import com.android.systemui.qs.tiles.di.QSTilesModule;
-import com.android.systemui.qs.ui.adapter.QSSceneAdapter;
-import com.android.systemui.qs.ui.adapter.QSSceneAdapterImpl;
-
-import java.util.Map;
-
-import dagger.Binds;
 import dagger.Module;
-import dagger.multibindings.Multibinds;
 
 /**
- * Module for QS dependencies
+ * Module for QS dependencies for AOSP inclusion
  */
-@Module(subcomponents = {QSFragmentComponent.class, QSSceneComponent.class},
-        includes = {
-                MediaModule.class,
-                PanelsModule.class,
-                QSFragmentComposeModule.class,
-                QSExternalModule.class,
-                QSFlagsModule.class,
-                QSHostModule.class,
-                QSPipelineModule.class,
-                QSTilesModule.class,
-        }
-)
-public interface QSModule {
-
-    /**
-     * A map of internal QS tiles. Ensures that this can be injected even if
-     * it is empty
-     */
-    @Multibinds
-    Map<String, QSTileImpl<?>> tileMap();
-
-    @Binds
-    QSSceneAdapter bindsQsSceneInteractor(QSSceneAdapterImpl impl);
-
-    /**
-     * Dims the screen
-     */
-    @Binds
-    ReduceBrightColorsController bindReduceBrightColorsController(
-            ReduceBrightColorsControllerImpl impl);
-}
+@Module(includes = { QSModuleBase.class})
+public interface QSModule { }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt
new file mode 100644
index 0000000..3fd8768
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.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.systemui.qs.dagger
+
+import com.android.systemui.media.dagger.MediaModule
+import com.android.systemui.qs.ReduceBrightColorsController
+import com.android.systemui.qs.ReduceBrightColorsControllerImpl
+import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeModule
+import com.android.systemui.qs.external.QSExternalModule
+import com.android.systemui.qs.panels.dagger.PanelsModule
+import com.android.systemui.qs.pipeline.dagger.QSPipelineModule
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.qs.tiles.di.QSTilesModule
+import com.android.systemui.qs.ui.adapter.QSSceneAdapter
+import com.android.systemui.qs.ui.adapter.QSSceneAdapterImpl
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.Multibinds
+
+/**
+ * QS Module for shared dependencies between AOSP and variants. Include this module in more
+ * specialized modules (like [QSModule]) and do not include this module directly in SystemUI modules
+ */
+@Module(
+    subcomponents = [QSFragmentComponent::class, QSSceneComponent::class],
+    includes =
+        [
+            MediaModule::class,
+            PanelsModule::class,
+            QSFragmentComposeModule::class,
+            QSExternalModule::class,
+            QSFlagsModule::class,
+            QSHostModule::class,
+            QSPipelineModule::class,
+            QSTilesModule::class,
+        ],
+)
+interface QSModuleBase {
+
+    /** A map of internal QS tiles. Ensures that this can be injected even if it is empty */
+    @Multibinds fun tileMap(): Map<String?, QSTileImpl<*>?>?
+
+    @Binds fun bindsQsSceneAdapter(impl: QSSceneAdapterImpl?): QSSceneAdapter?
+
+    /** Dims the screen */
+    @Binds
+    fun bindReduceBrightColorsController(
+        impl: ReduceBrightColorsControllerImpl?
+    ): ReduceBrightColorsController?
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt b/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
index ead38f3..ef45ae76 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
@@ -209,7 +209,7 @@
 
     // TODO(b/250618218): Remove this method once we know the root cause of b/250618218.
     fun logTileBackgroundColorUpdateIfInternetTile(
-        tileSpec: String,
+        tileSpec: String?,
         state: Int,
         disabledByPolicy: Boolean,
         color: Int,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt
index 35faa97..405ce8a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt
@@ -44,19 +44,28 @@
 /** Holds the [TileSpec] of the tile being moved and receives drag and drop events. */
 interface DragAndDropState {
     val draggedCell: SizedTile<EditTileViewModel>?
+    val draggedPosition: Offset
     val dragInProgress: Boolean
+    val dragType: DragType?
 
     fun isMoving(tileSpec: TileSpec): Boolean
 
-    fun onStarted(cell: SizedTile<EditTileViewModel>)
+    fun onStarted(cell: SizedTile<EditTileViewModel>, dragType: DragType)
 
-    fun onMoved(target: Int, insertAfter: Boolean)
+    fun onTargeting(target: Int, insertAfter: Boolean)
+
+    fun onMoved(offset: Offset)
 
     fun movedOutOfBounds()
 
     fun onDrop()
 }
 
+enum class DragType {
+    Add,
+    Move,
+}
+
 /**
  * Registers a composable as a [DragAndDropTarget] to receive drop events. Use this outside the tile
  * grid to catch out of bounds drops.
@@ -72,6 +81,10 @@
     val target =
         remember(dragAndDropState) {
             object : DragAndDropTarget {
+                override fun onMoved(event: DragAndDropEvent) {
+                    dragAndDropState.onMoved(event.toOffset())
+                }
+
                 override fun onDrop(event: DragAndDropEvent): Boolean {
                     return dragAndDropState.draggedCell?.let {
                         onDrop(it.tile.tileSpec)
@@ -117,8 +130,11 @@
                 }
 
                 override fun onMoved(event: DragAndDropEvent) {
+                    val offset = event.toOffset()
+                    dragAndDropState.onMoved(offset)
+
                     // Drag offset relative to the list's top left corner
-                    val relativeDragOffset = event.dragOffsetRelativeTo(contentOffset())
+                    val relativeDragOffset = offset - contentOffset()
                     val targetItem =
                         gridState.layoutInfo.visibleItemsInfo.firstOrNull { item ->
                             // Check if the drag is on this item
@@ -126,7 +142,7 @@
                         }
 
                     targetItem?.let {
-                        dragAndDropState.onMoved(it.index, insertAfter(it, relativeDragOffset))
+                        dragAndDropState.onTargeting(it.index, insertAfter(it, relativeDragOffset))
                     }
                 }
 
@@ -147,8 +163,8 @@
     )
 }
 
-private fun DragAndDropEvent.dragOffsetRelativeTo(offset: Offset): Offset {
-    return toAndroidDragEvent().run { Offset(x, y) } - offset
+private fun DragAndDropEvent.toOffset(): Offset {
+    return toAndroidDragEvent().run { Offset(x, y) }
 }
 
 private fun insertAfter(item: LazyGridItemInfo, offset: Offset): Boolean {
@@ -163,6 +179,7 @@
 fun Modifier.dragAndDropTileSource(
     sizedTile: SizedTile<EditTileViewModel>,
     dragAndDropState: DragAndDropState,
+    dragType: DragType,
     onDragStart: () -> Unit,
 ): Modifier {
     val dragState by rememberUpdatedState(dragAndDropState)
@@ -172,7 +189,7 @@
             detectDragGesturesAfterLongPress(
                 onDrag = { _, _ -> },
                 onDragStart = {
-                    dragState.onStarted(sizedTile)
+                    dragState.onStarted(sizedTile, dragType)
                     onDragStart()
 
                     // The tilespec from the ClipData transferred isn't actually needed as we're
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
index 14abfa2..8688558 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
@@ -17,10 +17,13 @@
 package com.android.systemui.qs.panels.ui.compose
 
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
 import androidx.compose.runtime.snapshots.SnapshotStateList
 import androidx.compose.runtime.toMutableStateList
+import androidx.compose.ui.geometry.Offset
 import com.android.systemui.qs.panels.shared.model.SizedTile
 import com.android.systemui.qs.panels.ui.model.GridCell
 import com.android.systemui.qs.panels.ui.model.TileGridCell
@@ -48,12 +51,17 @@
     private val columns: Int,
     private val largeTilesSpan: Int,
 ) : DragAndDropState {
-    private val _draggedCell = mutableStateOf<SizedTile<EditTileViewModel>?>(null)
-    override val draggedCell
-        get() = _draggedCell.value
+    override var draggedCell by mutableStateOf<SizedTile<EditTileViewModel>?>(null)
+        private set
+
+    override var draggedPosition by mutableStateOf(Offset.Unspecified)
+        private set
+
+    override var dragType by mutableStateOf<DragType?>(null)
+        private set
 
     override val dragInProgress: Boolean
-        get() = _draggedCell.value != null
+        get() = draggedCell != null
 
     private val _tiles: SnapshotStateList<GridCell> =
         tiles.toGridCells(columns).toMutableStateList()
@@ -83,18 +91,19 @@
     }
 
     override fun isMoving(tileSpec: TileSpec): Boolean {
-        return _draggedCell.value?.let { it.tile.tileSpec == tileSpec } ?: false
+        return draggedCell?.let { it.tile.tileSpec == tileSpec } ?: false
     }
 
-    override fun onStarted(cell: SizedTile<EditTileViewModel>) {
-        _draggedCell.value = cell
+    override fun onStarted(cell: SizedTile<EditTileViewModel>, dragType: DragType) {
+        draggedCell = cell
+        this.dragType = dragType
 
         // Add spacers to the grid to indicate where the user can move a tile
         regenerateGrid()
     }
 
-    override fun onMoved(target: Int, insertAfter: Boolean) {
-        val draggedTile = _draggedCell.value ?: return
+    override fun onTargeting(target: Int, insertAfter: Boolean) {
+        val draggedTile = draggedCell ?: return
 
         val fromIndex = indexOf(draggedTile.tile.tileSpec)
         if (fromIndex == target) {
@@ -115,16 +124,26 @@
         regenerateGrid()
     }
 
+    override fun onMoved(offset: Offset) {
+        draggedPosition = offset
+    }
+
     override fun movedOutOfBounds() {
-        val draggedTile = _draggedCell.value ?: return
+        val draggedTile = draggedCell ?: return
 
         _tiles.removeIf { cell ->
             cell is TileGridCell && cell.tile.tileSpec == draggedTile.tile.tileSpec
         }
+        draggedPosition = Offset.Unspecified
+
+        // Regenerate spacers without the dragged tile
+        regenerateGrid()
     }
 
     override fun onDrop() {
-        _draggedCell.value = null
+        draggedCell = null
+        draggedPosition = Offset.Unspecified
+        dragType = null
 
         // Remove the spacers
         regenerateGrid()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
index a05747d..d975f10 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
@@ -20,12 +20,16 @@
 
 import androidx.compose.animation.AnimatedContent
 import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.animateContentSize
+import androidx.compose.animation.core.LinearEasing
 import androidx.compose.animation.core.animateDpAsState
 import androidx.compose.animation.core.animateFloatAsState
+import androidx.compose.animation.core.tween
 import androidx.compose.animation.fadeIn
 import androidx.compose.animation.fadeOut
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.LocalOverscrollFactory
+import androidx.compose.foundation.ScrollState
 import androidx.compose.foundation.background
 import androidx.compose.foundation.border
 import androidx.compose.foundation.clipScrollableContainer
@@ -43,6 +47,7 @@
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.requiredHeightIn
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.wrapContentHeight
 import androidx.compose.foundation.layout.wrapContentSize
@@ -69,6 +74,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
@@ -80,6 +86,7 @@
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.draw.drawBehind
 import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.isSpecified
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.layout.MeasureScope
@@ -111,6 +118,7 @@
 import com.android.systemui.qs.panels.shared.model.SizedTileImpl
 import com.android.systemui.qs.panels.ui.compose.BounceableInfo
 import com.android.systemui.qs.panels.ui.compose.DragAndDropState
+import com.android.systemui.qs.panels.ui.compose.DragType
 import com.android.systemui.qs.panels.ui.compose.EditTileListState
 import com.android.systemui.qs.panels.ui.compose.bounceableInfo
 import com.android.systemui.qs.panels.ui.compose.dragAndDropRemoveZone
@@ -120,6 +128,9 @@
 import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.TileArrangementPadding
 import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.TileHeight
 import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.ToggleTargetSize
+import com.android.systemui.qs.panels.ui.compose.infinitegrid.EditModeTileDefaults.AUTO_SCROLL_DISTANCE
+import com.android.systemui.qs.panels.ui.compose.infinitegrid.EditModeTileDefaults.AUTO_SCROLL_SPEED
+import com.android.systemui.qs.panels.ui.compose.infinitegrid.EditModeTileDefaults.AvailableTilesGridMinHeight
 import com.android.systemui.qs.panels.ui.compose.infinitegrid.EditModeTileDefaults.CurrentTilesGridPadding
 import com.android.systemui.qs.panels.ui.compose.selection.MutableSelectionState
 import com.android.systemui.qs.panels.ui.compose.selection.ResizableTileContainer
@@ -139,8 +150,10 @@
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.shared.model.groupAndSort
 import com.android.systemui.res.R
+import kotlin.math.abs
 import kotlin.math.roundToInt
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.delay
 
 object TileType
@@ -201,8 +214,12 @@
     ) { innerPadding ->
         CompositionLocalProvider(LocalOverscrollFactory provides null) {
             val scrollState = rememberScrollState()
-            LaunchedEffect(listState.dragInProgress) {
-                if (listState.dragInProgress) {
+
+            AutoScrollGrid(listState, scrollState, innerPadding)
+
+            LaunchedEffect(listState.dragType) {
+                // Only scroll to the top when adding a new tile, not when reordering existing ones
+                if (listState.dragInProgress && listState.dragType == DragType.Add) {
                     scrollState.animateScrollTo(0)
                 }
             }
@@ -223,7 +240,7 @@
                 AnimatedContent(
                     targetState = listState.dragInProgress,
                     modifier = Modifier.wrapContentSize(),
-                    label = "",
+                    label = "QSEditHeader",
                 ) { dragIsInProgress ->
                     EditGridHeader(Modifier.dragAndDropRemoveZone(listState, onRemoveTile)) {
                         if (dragIsInProgress) {
@@ -243,37 +260,87 @@
                     onSetTiles,
                 )
 
-                // Hide available tiles when dragging
-                AnimatedVisibility(
-                    visible = !listState.dragInProgress,
-                    enter = fadeIn(),
-                    exit = fadeOut(),
+                // Sets a minimum height to be used when available tiles are hidden
+                Box(
+                    Modifier.fillMaxWidth()
+                        .requiredHeightIn(AvailableTilesGridMinHeight)
+                        .animateContentSize()
+                        .dragAndDropRemoveZone(listState, onRemoveTile)
                 ) {
-                    Column(
-                        verticalArrangement =
-                            spacedBy(dimensionResource(id = R.dimen.qs_label_container_margin)),
-                        modifier = modifier.fillMaxSize(),
+                    // Using the fully qualified name here as a workaround for AnimatedVisibility
+                    // not being available from a Box
+                    androidx.compose.animation.AnimatedVisibility(
+                        visible = !listState.dragInProgress,
+                        enter = fadeIn(),
+                        exit = fadeOut(),
                     ) {
-                        EditGridHeader {
-                            Text(text = stringResource(id = R.string.drag_to_add_tiles))
-                        }
+                        // Hide available tiles when dragging
+                        Column(
+                            verticalArrangement =
+                                spacedBy(dimensionResource(id = R.dimen.qs_label_container_margin)),
+                            modifier = modifier.fillMaxSize(),
+                        ) {
+                            EditGridHeader {
+                                Text(text = stringResource(id = R.string.drag_to_add_tiles))
+                            }
 
-                        AvailableTileGrid(otherTiles, selectionState, columns, listState)
+                            AvailableTileGrid(otherTiles, selectionState, columns, listState)
+                        }
                     }
                 }
-
-                // Drop zone to remove tiles dragged out of the tile grid
-                Spacer(
-                    modifier =
-                        Modifier.fillMaxWidth()
-                            .weight(1f)
-                            .dragAndDropRemoveZone(listState, onRemoveTile)
-                )
             }
         }
     }
 }
 
+@OptIn(ExperimentalCoroutinesApi::class)
+@Composable
+private fun AutoScrollGrid(
+    listState: EditTileListState,
+    scrollState: ScrollState,
+    padding: PaddingValues,
+) {
+    val density = LocalDensity.current
+    val (top, bottom) =
+        remember(density) {
+            with(density) {
+                padding.calculateTopPadding().roundToPx() to
+                    padding.calculateBottomPadding().roundToPx()
+            }
+        }
+    val scrollTarget by
+        remember(listState, scrollState, top, bottom) {
+            derivedStateOf {
+                val position = listState.draggedPosition
+                if (position.isSpecified) {
+                    // Return the scroll target needed based on the position of the drag movement,
+                    // or null if we don't need to scroll
+                    val y = position.y.roundToInt()
+                    when {
+                        y < AUTO_SCROLL_DISTANCE + top -> 0
+                        y > scrollState.viewportSize - bottom - AUTO_SCROLL_DISTANCE ->
+                            scrollState.maxValue
+                        else -> null
+                    }
+                } else {
+                    null
+                }
+            }
+        }
+    LaunchedEffect(scrollTarget) {
+        scrollTarget?.let {
+            // Change the duration of the animation based on the distance to maintain the
+            // same scrolling speed
+            val distance = abs(it - scrollState.value)
+            scrollState.animateScrollTo(
+                it,
+                animationSpec =
+                    tween(durationMillis = distance * AUTO_SCROLL_SPEED, easing = LinearEasing),
+            )
+        }
+    }
+}
+
 @Composable
 private fun EditGridHeader(
     modifier: Modifier = Modifier,
@@ -423,7 +490,7 @@
 }
 
 fun gridHeight(rows: Int, tileHeight: Dp, tilePadding: Dp, gridPadding: Dp): Dp {
-    return ((tileHeight + tilePadding) * rows) - tilePadding + gridPadding * 2
+    return ((tileHeight + tilePadding) * rows) + gridPadding * 2
 }
 
 private fun GridCell.key(index: Int, dragAndDropState: DragAndDropState): Any {
@@ -596,6 +663,7 @@
                 .dragAndDropTileSource(
                     SizedTileImpl(cell.tile, cell.width),
                     dragAndDropState,
+                    DragType.Move,
                     selectionState::unSelect,
                 )
                 .tileBackground(colors.background)
@@ -631,7 +699,11 @@
                     onClick(onClickActionName) { false }
                     this.stateDescription = stateDescription
                 }
-                .dragAndDropTileSource(SizedTileImpl(cell.tile, cell.width), dragAndDropState) {
+                .dragAndDropTileSource(
+                    SizedTileImpl(cell.tile, cell.width),
+                    dragAndDropState,
+                    DragType.Add,
+                ) {
                     selectionState.unSelect()
                 }
                 .tileBackground(colors.background)
@@ -739,7 +811,10 @@
 
 private object EditModeTileDefaults {
     const val PLACEHOLDER_ALPHA = .3f
+    const val AUTO_SCROLL_DISTANCE = 100
+    const val AUTO_SCROLL_SPEED = 2 // 2ms per pixel
     val CurrentTilesGridPadding = 8.dp
+    val AvailableTilesGridMinHeight = 200.dp
 
     @Composable
     fun editTileColors(): TileColors =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
index faab696..f7ed1ad 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
@@ -18,9 +18,14 @@
 
 import android.content.Context
 import androidx.compose.ui.util.fastMap
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListUpdateCallback
+import com.android.internal.logging.UiEventLogger
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.qs.QSEditEvent
 import com.android.systemui.qs.panels.domain.interactor.EditTilesListInteractor
 import com.android.systemui.qs.panels.domain.interactor.GridLayoutTypeInteractor
 import com.android.systemui.qs.panels.domain.interactor.TilesAvailabilityInteractor
@@ -30,10 +35,12 @@
 import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor.Companion.POSITION_AT_END
 import com.android.systemui.qs.pipeline.domain.interactor.MinimumTilesInteractor
 import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.pipeline.shared.metricSpec
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.util.kotlin.emitOnStart
 import javax.inject.Inject
 import javax.inject.Named
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -45,6 +52,7 @@
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
 
 @SysUISingleton
 @OptIn(ExperimentalCoroutinesApi::class)
@@ -55,10 +63,12 @@
     private val currentTilesInteractor: CurrentTilesInteractor,
     private val tilesAvailabilityInteractor: TilesAvailabilityInteractor,
     private val minTilesInteractor: MinimumTilesInteractor,
+    private val uiEventLogger: UiEventLogger,
     @ShadeDisplayAware private val configurationInteractor: ConfigurationInteractor,
-    @ShadeDisplayAware  private val context: Context,
+    @ShadeDisplayAware private val context: Context,
     @Named("Default") private val defaultGridLayout: GridLayout,
     @Application private val applicationScope: CoroutineScope,
+    @Background private val bgDispatcher: CoroutineDispatcher,
     gridLayoutTypeInteractor: GridLayoutTypeInteractor,
     gridLayoutMap: Map<GridLayoutType, @JvmSuppressWildcards GridLayout>,
 ) {
@@ -149,11 +159,17 @@
 
     /** @see isEditing */
     fun startEditing() {
+        if (!isEditing.value) {
+            uiEventLogger.log(QSEditEvent.QS_EDIT_OPEN)
+        }
         _isEditing.value = true
     }
 
     /** @see isEditing */
     fun stopEditing() {
+        if (isEditing.value) {
+            uiEventLogger.log(QSEditEvent.QS_EDIT_CLOSED)
+        }
         _isEditing.value = false
     }
 
@@ -164,6 +180,7 @@
     fun addTile(tileSpec: TileSpec, position: Int = POSITION_AT_END) {
         val specs = currentTilesInteractor.currentTilesSpecs.toMutableList()
         val currentPosition = specs.indexOf(tileSpec)
+        val moved = currentPosition != -1
 
         if (currentPosition != -1) {
             // No operation needed if the element is already in the list at the right position
@@ -179,6 +196,12 @@
         } else {
             specs.add(tileSpec)
         }
+        uiEventLogger.logWithPosition(
+            if (moved) QSEditEvent.QS_EDIT_MOVE else QSEditEvent.QS_EDIT_ADD,
+            /* uid= */ 0,
+            /* packageName= */ tileSpec.metricSpec,
+            if (moved && position == POSITION_AT_END) specs.size - 1 else position,
+        )
 
         // Setting the new tiles as one operation to avoid UI jank with tiles disappearing and
         // reappearing
@@ -187,10 +210,80 @@
 
     /** Immediately removes [tileSpec] from the current tiles. */
     fun removeTile(tileSpec: TileSpec) {
+        uiEventLogger.log(
+            QSEditEvent.QS_EDIT_REMOVE,
+            /* uid= */ 0,
+            /* packageName= */ tileSpec.metricSpec,
+        )
         currentTilesInteractor.removeTiles(listOf(tileSpec))
     }
 
     fun setTiles(tileSpecs: List<TileSpec>) {
+        val currentTiles = currentTilesInteractor.currentTilesSpecs
         currentTilesInteractor.setTiles(tileSpecs)
+        applicationScope.launch(bgDispatcher) {
+            calculateDiffsAndEmitUiEvents(currentTiles, tileSpecs)
+        }
+    }
+
+    private fun calculateDiffsAndEmitUiEvents(
+        currentTiles: List<TileSpec>,
+        newTiles: List<TileSpec>,
+    ) {
+        val listDiff = DiffUtil.calculateDiff(DiffCallback(currentTiles, newTiles))
+        listDiff.dispatchUpdatesTo(
+            object : ListUpdateCallback {
+                override fun onInserted(position: Int, count: Int) {
+                    newTiles.getOrNull(position)?.let {
+                        uiEventLogger.logWithPosition(
+                            QSEditEvent.QS_EDIT_ADD,
+                            /* uid= */ 0,
+                            /* packageName= */ it.metricSpec,
+                            position,
+                        )
+                    }
+                }
+
+                override fun onRemoved(position: Int, count: Int) {
+                    currentTiles.getOrNull(position)?.let {
+                        uiEventLogger.log(QSEditEvent.QS_EDIT_REMOVE, 0, it.metricSpec)
+                    }
+                }
+
+                override fun onMoved(fromPosition: Int, toPosition: Int) {
+                    currentTiles.getOrNull(fromPosition)?.let {
+                        uiEventLogger.logWithPosition(
+                            QSEditEvent.QS_EDIT_MOVE,
+                            /* uid= */ 0,
+                            /* packageName= */ it.metricSpec,
+                            toPosition,
+                        )
+                    }
+                }
+
+                override fun onChanged(position: Int, count: Int, payload: Any?) {}
+            }
+        )
+    }
+}
+
+private class DiffCallback(
+    private val currentList: List<TileSpec>,
+    private val newList: List<TileSpec>,
+) : DiffUtil.Callback() {
+    override fun getOldListSize(): Int {
+        return currentList.size
+    }
+
+    override fun getNewListSize(): Int {
+        return newList.size
+    }
+
+    override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
+        return currentList[oldItemPosition] == newList[newItemPosition]
+    }
+
+    override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
+        return areItemsTheSame(oldItemPosition, newItemPosition)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt
index 2e52845..16c2722 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt
@@ -34,10 +34,7 @@
     data object Invalid : TileSpec("")
 
     /** Container for the spec of a tile provided by SystemUI. */
-    data class PlatformTileSpec
-    internal constructor(
-        override val spec: String,
-    ) : TileSpec(spec) {
+    data class PlatformTileSpec internal constructor(override val spec: String) : TileSpec(spec) {
         override fun toString(): String {
             return "P($spec)"
         }
@@ -49,10 +46,8 @@
      * [componentName] indicates the associated `TileService`.
      */
     data class CustomTileSpec
-    internal constructor(
-        override val spec: String,
-        val componentName: ComponentName,
-    ) : TileSpec(spec) {
+    internal constructor(override val spec: String, val componentName: ComponentName) :
+        TileSpec(spec) {
         override fun toString(): String {
             return "C(${componentName.flattenToShortString()})"
         }
@@ -92,3 +87,11 @@
                 }
     }
 }
+
+val TileSpec.metricSpec
+    get() =
+        when (this) {
+            is TileSpec.Invalid -> ""
+            is TileSpec.PlatformTileSpec -> spec
+            is TileSpec.CustomTileSpec -> componentName.packageName
+        }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
index deeef55..42a0cb1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -102,7 +102,7 @@
         // Show a dialog to confirm first. Dialogs shown by the DialogTransitionAnimator must be
         // created and shown on the main thread, so we post it to the UI handler.
         mUiHandler.post(() -> {
-            SystemUIDialog dialog = mSystemUIDialogFactory.create();
+            SystemUIDialog dialog = mSystemUIDialogFactory.create(mContext);
             dialog.setTitle(com.android.internal.R.string.data_saver_enable_title);
             dialog.setMessage(com.android.internal.R.string.data_saver_description);
             dialog.setPositiveButton(com.android.internal.R.string.data_saver_enable_button,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
index 4fb96e7..ec8d30b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
@@ -24,6 +24,7 @@
 import android.service.quicksettings.Tile;
 import android.text.TextUtils;
 import android.util.Log;
+import android.widget.Button;
 import android.widget.Switch;
 
 import androidx.annotation.Nullable;
@@ -144,8 +145,10 @@
         // Show expand icon when clicking will open a dialog
         state.forceExpandIcon = state.state == Tile.STATE_INACTIVE;
 
+        state.expandedAccessibilityClassName = Button.class.getName();
         if (isRecording) {
             state.secondaryLabel = mContext.getString(R.string.quick_settings_screen_record_stop);
+            state.expandedAccessibilityClassName = Switch.class.getName();
         } else if (isStarting) {
             int countdown =
                     (int) ScreenRecordModel.Starting.Companion.toCountdownSeconds(
@@ -157,7 +160,6 @@
         state.contentDescription = TextUtils.isEmpty(state.secondaryLabel)
                 ? state.label
                 : TextUtils.concat(state.label, ", ", state.secondaryLabel);
-        state.expandedAccessibilityClassName = Switch.class.getName();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileCoroutineScopeFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileCoroutineScopeFactory.kt
index dde3628..5f476ea 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileCoroutineScopeFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileCoroutineScopeFactory.kt
@@ -17,18 +17,17 @@
 package com.android.systemui.qs.tiles.base.viewmodel
 
 import com.android.systemui.coroutines.newTracingContext
-import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.SupervisorJob
 
 /** Creates a [CoroutineScope] for the [QSTileViewModelImpl]. */
 class QSTileCoroutineScopeFactory
 @Inject
-constructor(@Application private val applicationScope: CoroutineScope) {
+constructor(@Background private val bgDispatcher: CoroutineDispatcher) {
 
     fun create(): CoroutineScope =
-        CoroutineScope(
-            applicationScope.coroutineContext + SupervisorJob() + newTracingContext("QSTileScope")
-        )
+        CoroutineScope(bgDispatcher + SupervisorJob() + newTracingContext("QSTileScope"))
 }
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 bed8021..dbe1ae9 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
@@ -195,8 +195,11 @@
     private boolean mHasWifiEntries;
     private WifiStateWorker mWifiStateWorker;
     private boolean mHasActiveSubIdOnDds;
+    private boolean mIsMobileDataEnabled = false;
 
     @VisibleForTesting
+    Map<Integer, ServiceState> mSubIdServiceState = new HashMap<>();
+    @VisibleForTesting
     static final float TOAST_PARAMS_HORIZONTAL_WEIGHT = 1.0f;
     @VisibleForTesting
     static final float TOAST_PARAMS_VERTICAL_WEIGHT = 1.0f;
@@ -453,7 +456,7 @@
             return mContext.getText(SUBTITLE_TEXT_ALL_CARRIER_NETWORK_UNAVAILABLE);
         }
 
-        if (mCanConfigWifi && !isMobileDataEnabled()) {
+        if (mCanConfigWifi && !mIsMobileDataEnabled) {
             if (DEBUG) {
                 Log.d(TAG, "Mobile data off");
             }
@@ -551,7 +554,7 @@
             numLevels += 1;
         }
         return getSignalStrengthIcon(subId, mContext, level, numLevels, NO_CELL_DATA_TYPE_ICON,
-                !isMobileDataEnabled());
+                !mIsMobileDataEnabled);
     }
 
     Drawable getSignalStrengthIcon(int subId, Context context, int level, int numLevels,
@@ -681,6 +684,12 @@
             // sets the non-DDS to be not found to hide its visual
             return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
         }
+        int activeDataSubId = SubscriptionManager.getActiveDataSubscriptionId();
+        if (activeDataSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID
+                || mDefaultDataSubId == activeDataSubId) {
+            return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        }
+
         SubscriptionInfo subInfo = mSubscriptionManager.getActiveSubscriptionInfo(
                 SubscriptionManager.getActiveDataSubscriptionId());
         if (subInfo != null && subInfo.getSubscriptionId() != mDefaultDataSubId
@@ -740,7 +749,6 @@
         if (!isMobileDataEnabled()) {
             return context.getString(R.string.mobile_data_off_summary);
         }
-
         String summary = networkTypeDescription;
         boolean isForDds = subId == mDefaultDataSubId;
         int activeSubId = getActiveAutoSwitchNonDdsSubId();
@@ -753,8 +761,8 @@
                     context.getString(
                             isForDds // if nonDds is active, explains Dds status as poor connection
                                     ? (isOnNonDds ? R.string.mobile_data_poor_connection
-                                            : R.string.mobile_data_connection_active)
-                            : R.string.mobile_data_temp_connection_active),
+                                    : R.string.mobile_data_connection_active)
+                                    : R.string.mobile_data_temp_connection_active),
                     networkTypeDescription);
         } else if (!isDataStateInService(subId)) {
             summary = context.getString(R.string.mobile_data_no_connection);
@@ -963,10 +971,7 @@
      * Return {@code true} if mobile data is enabled
      */
     boolean isMobileDataEnabled() {
-        if (mTelephonyManager == null || !mTelephonyManager.isDataEnabled()) {
-            return false;
-        }
-        return true;
+        return mIsMobileDataEnabled;
     }
 
     /**
@@ -1019,8 +1024,8 @@
     }
 
     boolean isDataStateInService(int subId) {
-        TelephonyManager tm = mSubIdTelephonyManagerMap.getOrDefault(subId, mTelephonyManager);
-        final ServiceState serviceState = tm.getServiceState();
+        final ServiceState serviceState = mSubIdServiceState.getOrDefault(subId,
+                new ServiceState());
         NetworkRegistrationInfo regInfo =
                 (serviceState == null) ? null : serviceState.getNetworkRegistrationInfo(
                         NetworkRegistrationInfo.DOMAIN_PS,
@@ -1036,8 +1041,8 @@
             return false;
         }
 
-        TelephonyManager tm = mSubIdTelephonyManagerMap.getOrDefault(subId, mTelephonyManager);
-        final ServiceState serviceState = tm.getServiceState();
+        final ServiceState serviceState = mSubIdServiceState.getOrDefault(subId,
+                new ServiceState());
         return serviceState != null
                 && serviceState.getState() == serviceState.STATE_IN_SERVICE;
     }
@@ -1056,6 +1061,7 @@
 
         final Network activeNetwork = mConnectivityManager.getActiveNetwork();
         if (activeNetwork == null) {
+            Log.d(TAG, "getActiveNetwork is null.");
             return false;
         }
         final NetworkCapabilities networkCapabilities =
@@ -1183,14 +1189,16 @@
     }
 
     private class InternetTelephonyCallback extends TelephonyCallback implements
+            TelephonyCallback.DataEnabledListener,
             TelephonyCallback.DataConnectionStateListener,
             TelephonyCallback.DisplayInfoListener,
             TelephonyCallback.ServiceStateListener,
             TelephonyCallback.SignalStrengthsListener,
             TelephonyCallback.UserMobileDataStateListener,
-            TelephonyCallback.CarrierNetworkListener{
+            TelephonyCallback.CarrierNetworkListener {
 
         private final int mSubId;
+
         private InternetTelephonyCallback(int subId) {
             mSubId = subId;
         }
@@ -1200,6 +1208,7 @@
             if (mCallback != null) {
                 mCallback.onServiceStateChanged(serviceState);
             }
+            mSubIdServiceState.put(mSubId, serviceState);
         }
 
         @Override
@@ -1238,6 +1247,13 @@
                 mCallback.onCarrierNetworkChange(active);
             }
         }
+
+        @Override
+        public void onDataEnabledChanged(boolean b, int i) {
+            if (mSubId == mDefaultDataSubId) {
+                mIsMobileDataEnabled = b;
+            }
+        }
     }
 
     private class InternetOnSubscriptionChangedListener
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
index 0ab533b..70c2a2a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
@@ -104,6 +104,7 @@
     private final Handler mHandler;
     private final Executor mBackgroundExecutor;
     private final DialogTransitionAnimator mDialogTransitionAnimator;
+    private final Context mContext;
     private final boolean mAboveStatusBar;
     private final SystemUIDialog.Factory mSystemUIDialogFactory;
 
@@ -204,6 +205,7 @@
             @Background Executor executor,
             KeyguardStateController keyguardStateController,
             SystemUIDialog.Factory systemUIDialogFactory) {
+        mContext = context;
         mAboveStatusBar = aboveStatusBar;
         mSystemUIDialogFactory = systemUIDialogFactory;
         if (DEBUG) {
@@ -228,7 +230,7 @@
 
     @Override
     public SystemUIDialog createDialog() {
-        SystemUIDialog dialog = mSystemUIDialogFactory.create(this);
+        SystemUIDialog dialog = mSystemUIDialogFactory.create(this, mContext);
         if (!mAboveStatusBar) {
             dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
         }
@@ -416,9 +418,10 @@
         internetContent.mHasEthernet = mInternetDialogController.hasEthernet();
         internetContent.mIsWifiEnabled = mInternetDialogController.isWifiEnabled();
         internetContent.mHasActiveSubIdOnDds = mInternetDialogController.hasActiveSubIdOnDds();
-        internetContent.mIsMobileDataEnabled = mInternetDialogController.isMobileDataEnabled();
         internetContent.mIsDeviceLocked = mInternetDialogController.isDeviceLocked();
         internetContent.mIsWifiScanEnabled = mInternetDialogController.isWifiScanEnabled();
+        internetContent.mActiveAutoSwitchNonDdsSubId =
+                mInternetDialogController.getActiveAutoSwitchNonDdsSubId();
         return internetContent;
     }
 
@@ -433,7 +436,11 @@
 
     private void setOnClickListener(SystemUIDialog dialog) {
         mMobileNetworkLayout.setOnClickListener(v -> {
-            int autoSwitchNonDdsSubId = mInternetDialogController.getActiveAutoSwitchNonDdsSubId();
+            int autoSwitchNonDdsSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+            if (mDataInternetContent.getValue() != null) {
+                autoSwitchNonDdsSubId =
+                        mDataInternetContent.getValue().mActiveAutoSwitchNonDdsSubId;
+            }
             if (autoSwitchNonDdsSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
                 showTurnOffAutoDataSwitchDialog(dialog, autoSwitchNonDdsSubId);
             }
@@ -524,7 +531,7 @@
             }
         } else {
             mMobileNetworkLayout.setVisibility(View.VISIBLE);
-            mMobileDataToggle.setChecked(internetContent.mIsMobileDataEnabled);
+            mMobileDataToggle.setChecked(mInternetDialogController.isMobileDataEnabled());
             mMobileTitleText.setText(getMobileNetworkTitle(mDefaultDataSubId));
             String summary = getMobileNetworkSummary(mDefaultDataSubId);
             if (!TextUtils.isEmpty(summary)) {
@@ -549,9 +556,9 @@
                     ? R.color.connected_network_primary_color
                     : R.color.disconnected_network_primary_color;
             mMobileToggleDivider.setBackgroundColor(dialog.getContext().getColor(primaryColor));
-
             // Display the info for the non-DDS if it's actively being used
-            int autoSwitchNonDdsSubId = mInternetDialogController.getActiveAutoSwitchNonDdsSubId();
+            int autoSwitchNonDdsSubId = internetContent.mActiveAutoSwitchNonDdsSubId;
+
             int nonDdsVisibility = autoSwitchNonDdsSubId
                     != SubscriptionManager.INVALID_SUBSCRIPTION_ID ? View.VISIBLE : View.GONE;
 
@@ -983,8 +990,8 @@
         boolean mIsCarrierNetworkActive = false;
         boolean mIsWifiEnabled = false;
         boolean mHasActiveSubIdOnDds = false;
-        boolean mIsMobileDataEnabled = false;
         boolean mIsDeviceLocked = false;
         boolean mIsWifiScanEnabled = false;
+        int mActiveAutoSwitchNonDdsSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt
index fdb15b9..c4f9515 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt
@@ -30,11 +30,6 @@
 import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel
 import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import com.android.systemui.statusbar.connectivity.AccessPointController
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOn
-import kotlinx.coroutines.flow.stateIn
 import javax.inject.Inject
 import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.withContext
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverDialogDelegate.kt
index 671943c..d0f2580 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverDialogDelegate.kt
@@ -20,18 +20,19 @@
 import android.content.DialogInterface
 import android.content.SharedPreferences
 import android.os.Bundle
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.internal.R
 import com.android.systemui.coroutines.newTracingContext
 import com.android.systemui.qs.tiles.impl.saver.domain.interactor.DataSaverTileUserActionInteractor
+import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.statusbar.policy.DataSaverController
 import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.CoroutineScope
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 class DataSaverDialogDelegate(
     private val sysuiDialogFactory: SystemUIDialog.Factory,
-    private val context: Context,
+    @ShadeDisplayAware private val context: Context,
     private val backgroundContext: CoroutineContext,
     private val dataSaverController: DataSaverController,
     private val sharedPreferences: SharedPreferences,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt b/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
index 95e7f56..8c54ab40 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
@@ -25,7 +25,6 @@
 import android.view.LayoutInflater
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.logging.UiEventLogger
-import com.android.systemui.res.R
 import com.android.systemui.animation.DialogCuj
 import com.android.systemui.animation.DialogTransitionAnimator
 import com.android.systemui.animation.Expandable
@@ -34,22 +33,23 @@
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.qs.QSUserSwitcherEvent
 import com.android.systemui.qs.tiles.UserDetailView
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.user.ui.dialog.DialogShowerImpl
 import javax.inject.Inject
 import javax.inject.Provider
 
-/**
- * Controller for [UserDialog].
- */
+/** Controller for [UserDialog]. */
 @SysUISingleton
-class UserSwitchDialogController @Inject constructor(
+class UserSwitchDialogController
+@Inject
+constructor(
     private val userDetailViewAdapterProvider: Provider<UserDetailView.Adapter>,
     private val activityStarter: ActivityStarter,
     private val falsingManager: FalsingManager,
     private val dialogTransitionAnimator: DialogTransitionAnimator,
     private val uiEventLogger: UiEventLogger,
-    private val dialogFactory: SystemUIDialog.Factory
+    private val dialogFactory: SystemUIDialog.Factory,
 ) {
 
     companion object {
@@ -64,7 +64,7 @@
      * [userDetailViewAdapterProvider] and show it as launched from [expandable].
      */
     fun showDialog(context: Context, expandable: Expandable) {
-        with(dialogFactory.create()) {
+        with(dialogFactory.create(context)) {
             setShowForAllUsers(true)
             setCanceledOnTouchOutside(true)
 
@@ -72,24 +72,31 @@
             setPositiveButton(R.string.quick_settings_done) { _, _ ->
                 uiEventLogger.log(QSUserSwitcherEvent.QS_USER_DETAIL_CLOSE)
             }
-            setNeutralButton(R.string.quick_settings_more_user_settings, { _, _ ->
-                if (!falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
-                    uiEventLogger.log(QSUserSwitcherEvent.QS_USER_MORE_SETTINGS)
-                    val controller = dialogTransitionAnimator.createActivityTransitionController(
-                        getButton(BUTTON_NEUTRAL)
-                    )
+            setNeutralButton(
+                R.string.quick_settings_more_user_settings,
+                { _, _ ->
+                    if (!falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
+                        uiEventLogger.log(QSUserSwitcherEvent.QS_USER_MORE_SETTINGS)
+                        val controller =
+                            dialogTransitionAnimator.createActivityTransitionController(
+                                getButton(BUTTON_NEUTRAL)
+                            )
 
-                    if (controller == null) {
-                        dismiss()
+                        if (controller == null) {
+                            dismiss()
+                        }
+
+                        activityStarter.postStartActivityDismissingKeyguard(
+                            USER_SETTINGS_INTENT,
+                            0,
+                            controller,
+                        )
                     }
-
-                    activityStarter.postStartActivityDismissingKeyguard(
-                        USER_SETTINGS_INTENT, 0, controller
-                    )
-                }
-            }, false /* dismissOnClick */)
-            val gridFrame = LayoutInflater.from(this.context)
-                .inflate(R.layout.qs_user_dialog_content, null)
+                },
+                false, /* dismissOnClick */
+            )
+            val gridFrame =
+                LayoutInflater.from(this.context).inflate(R.layout.qs_user_dialog_content, null)
             setView(gridFrame)
 
             val adapter = userDetailViewAdapterProvider.get()
@@ -101,10 +108,7 @@
                     DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, INTERACTION_JANK_TAG)
                 )
             if (controller != null) {
-                dialogTransitionAnimator.show(
-                    this,
-                    controller,
-                )
+                dialogTransitionAnimator.show(this, controller)
             } else {
                 show()
             }
diff --git a/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java b/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java
index 9a1ffcb..3c03d28 100644
--- a/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java
@@ -35,6 +35,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.ColorUtils;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import static com.android.systemui.Flags.notificationShadeBlur;
 
 /**
  * Drawable used on SysUI scrims.
@@ -213,6 +214,10 @@
     public void draw(@NonNull Canvas canvas) {
         mPaint.setColor(mMainColor);
         mPaint.setAlpha(mAlpha);
+        if (notificationShadeBlur()) {
+            // TODO(b/370555223): Match the alpha to the visual spec when it is finalized.
+            mPaint.setAlpha((int) (0.5f * mAlpha));
+        }
         if (mConcaveInfo != null) {
             drawConcave(canvas);
         } else if (mCornerRadiusEnabled && mCornerRadius > 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java b/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java
index 49f3cfc..4bfa61e 100644
--- a/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java
@@ -44,6 +44,8 @@
 
 import java.util.concurrent.Executor;
 
+import static com.android.systemui.Flags.notificationShadeBlur;
+
 /**
  * A view which can draw a scrim.  This view maybe be used in multiple windows running on different
  * threads, but is controlled by {@link com.android.systemui.statusbar.phone.ScrimController} so we
@@ -250,6 +252,10 @@
             if (mBlendWithMainColor) {
                 mainTinted = ColorUtils.blendARGB(mColors.getMainColor(), mTintColor, tintAmount);
             }
+            if (notificationShadeBlur()) {
+                // TODO(b/370555223): Fix color and transparency to match visual spec exactly
+                mainTinted = ColorUtils.blendARGB(mColors.getMainColor(), Color.GRAY, 0.5f);
+            }
             drawable.setColor(mainTinted, animated);
         } else {
             boolean hasAlpha = Color.alpha(mTintColor) != 0;
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
index fc4db08..b7a3aed 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
@@ -31,6 +31,8 @@
 import android.util.Log
 import androidx.annotation.GuardedBy
 import androidx.annotation.WorkerThread
+import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.app.tracing.traceSection
 import com.android.systemui.Dumpable
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.flags.FeatureFlagsClassic
@@ -49,7 +51,6 @@
 import kotlinx.coroutines.asCoroutineDispatcher
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.delay
-import com.android.app.tracing.coroutines.launchTraced as launch
 import kotlinx.coroutines.sync.Mutex
 
 /**
@@ -314,7 +315,9 @@
         list.forEach {
             val callback = it.callback.get()
             if (callback != null) {
-                it.executor.execute { action(callback) { latch.countDown() } }
+                it.executor.execute {
+                    traceSection({ "$callback" }) { action(callback) { latch.countDown() } }
+                }
             } else {
                 latch.countDown()
             }
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSeekBar.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSeekBar.java
index 30b68927..c241f21 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSeekBar.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSeekBar.java
@@ -62,7 +62,7 @@
         } else if (event.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
             setHovered(false);
         }
-        return true;
+        return super.onHoverEvent(event);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 3a6c250..d347084 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -3185,7 +3185,7 @@
             return false;
         }
         if (mHeadsUpAppearanceController != null
-                && mHeadsUpAppearanceController.shouldBeVisible()) {
+                && mHeadsUpAppearanceController.shouldHeadsUpStatusBarBeVisible()) {
             return false;
         }
         return !mShowIconsWhenExpanded;
@@ -4634,7 +4634,7 @@
                 @Override
                 public boolean shouldHeadsUpBeVisible() {
                     return mHeadsUpAppearanceController != null &&
-                            mHeadsUpAppearanceController.shouldBeVisible();
+                            mHeadsUpAppearanceController.shouldHeadsUpStatusBarBeVisible();
                 }
 
                 @Override
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
index f5fc1f4..bf672be 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
@@ -166,6 +166,15 @@
     }
 
     @Override
+    public void onMovedToDisplay(int displayId, Configuration config) {
+        super.onMovedToDisplay(displayId, config);
+        ShadeWindowGoesAround.isUnexpectedlyInLegacyMode();
+        // When the window is moved we're only receiving a call to this method instead of the
+        // onConfigurationChange itself. Let's just trigegr a normal config change.
+        onConfigurationChanged(config);
+    }
+
+    @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
         if (mConfigurationForwarder != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
index ff39a3d..d31868c 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
@@ -22,15 +22,16 @@
 import android.view.WindowManager
 import android.view.WindowManager.LayoutParams
 import android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE
+import android.window.WindowContext
 import com.android.systemui.CoreStartable
 import com.android.systemui.common.ui.ConfigurationState
 import com.android.systemui.common.ui.ConfigurationStateImpl
-import com.android.systemui.common.ui.GlobalConfig
 import com.android.systemui.common.ui.data.repository.ConfigurationRepository
 import com.android.systemui.common.ui.data.repository.ConfigurationRepositoryImpl
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractorImpl
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.res.R
 import com.android.systemui.scene.ui.view.WindowRootView
 import com.android.systemui.shade.data.repository.MutableShadeDisplaysRepository
@@ -48,6 +49,7 @@
 import dagger.multibindings.ClassKey
 import dagger.multibindings.IntoMap
 import javax.inject.Provider
+import javax.inject.Qualifier
 
 /**
  * Module responsible for managing display-specific components and resources for the notification
@@ -81,6 +83,19 @@
     @Provides
     @ShadeDisplayAware
     @SysUISingleton
+    fun provideShadeDisplayAwareWindowContext(@ShadeDisplayAware context: Context): WindowContext {
+        ShadeWindowGoesAround.isUnexpectedlyInLegacyMode()
+        // We rely on the fact context is a WindowContext as the API to reparent windows is only
+        // available there.
+        return (context as? WindowContext)
+            ?: error(
+                "ShadeDisplayAware context must be a window context to allow window reparenting."
+            )
+    }
+
+    @Provides
+    @ShadeDisplayAware
+    @SysUISingleton
     fun provideShadeWindowLayoutParams(@ShadeDisplayAware context: Context): LayoutParams {
         return ShadeWindowLayoutParams.create(context)
     }
@@ -119,7 +134,7 @@
     fun provideShadeWindowConfigurationController(
         @ShadeDisplayAware shadeContext: Context,
         factory: ConfigurationControllerImpl.Factory,
-        @GlobalConfig globalConfigController: ConfigurationController,
+        @Main globalConfigController: ConfigurationController,
     ): ConfigurationController {
         return if (ShadeWindowGoesAround.isEnabled) {
             factory.create(shadeContext)
@@ -145,7 +160,7 @@
         factory: ConfigurationStateImpl.Factory,
         @ShadeDisplayAware configurationController: ConfigurationController,
         @ShadeDisplayAware context: Context,
-        @GlobalConfig configurationState: ConfigurationState,
+        @Main configurationState: ConfigurationState,
     ): ConfigurationState {
         return if (ShadeWindowGoesAround.isEnabled) {
             factory.create(context, configurationController)
@@ -161,7 +176,7 @@
         factory: ConfigurationRepositoryImpl.Factory,
         @ShadeDisplayAware configurationController: ConfigurationController,
         @ShadeDisplayAware context: Context,
-        @GlobalConfig globalConfigurationRepository: ConfigurationRepository,
+        @Main globalConfigurationRepository: ConfigurationRepository,
     ): ConfigurationRepository {
         return if (ShadeWindowGoesAround.isEnabled) {
             factory.create(context, configurationController)
@@ -175,7 +190,7 @@
     @ShadeDisplayAware
     fun provideShadeAwareConfigurationInteractor(
         @ShadeDisplayAware configurationRepository: ConfigurationRepository,
-        @GlobalConfig configurationInteractor: ConfigurationInteractor,
+        @Main configurationInteractor: ConfigurationInteractor,
     ): ConfigurationInteractor {
         return if (ShadeWindowGoesAround.isEnabled) {
             ConfigurationInteractorImpl(configurationRepository)
@@ -203,7 +218,9 @@
     @Provides
     @IntoMap
     @ClassKey(ShadePrimaryDisplayCommand::class)
-    fun provideShadePrimaryDisplayCommand(impl: Provider<ShadePrimaryDisplayCommand>): CoreStartable {
+    fun provideShadePrimaryDisplayCommand(
+        impl: Provider<ShadePrimaryDisplayCommand>
+    ): CoreStartable {
         return if (ShadeWindowGoesAround.isEnabled) {
             impl.get()
         } else {
@@ -221,9 +238,23 @@
             CoreStartable.NOP
         }
     }
+
+    @Provides
+    @ShadeOnDefaultDisplayWhenLocked
+    fun provideShadeOnDefaultDisplayWhenLocked(): Boolean = true
 }
 
 @Module
 internal interface OptionalShadeDisplayAwareBindings {
     @BindsOptionalOf fun bindOptionalOfWindowRootView(): WindowRootView
 }
+
+/**
+ * Annotates the boolean value that defines whether the shade window should go back to the default
+ * display when the keyguard is visible.
+ *
+ * As of today (Dec 2024), This is a configuration parameter provided in the dagger graph as the
+ * final policy around keyguard display is still under discussion, and will be evaluated based on
+ * how well this solution behaves from the performance point of view.
+ */
+@Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class ShadeOnDefaultDisplayWhenLocked
diff --git a/packages/SystemUI/src/com/android/systemui/shade/StatusBarLongPressGestureDetector.kt b/packages/SystemUI/src/com/android/systemui/shade/StatusBarLongPressGestureDetector.kt
index ae36e81..29c7aa0 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/StatusBarLongPressGestureDetector.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/StatusBarLongPressGestureDetector.kt
@@ -21,13 +21,18 @@
 import android.view.GestureDetector.SimpleOnGestureListener
 import android.view.MotionEvent
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
 import javax.inject.Inject
 
 /** Accepts touch events, detects long press, and calls ShadeViewController#onStatusBarLongPress. */
 @SysUISingleton
 class StatusBarLongPressGestureDetector
 @Inject
-constructor(context: Context, val shadeViewController: ShadeViewController) {
+constructor(
+    // TODO b/383125226 - Make this class per-display
+    @Main context: Context,
+    val shadeViewController: ShadeViewController,
+) {
     val gestureDetector =
         GestureDetector(
             context,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicy.kt b/packages/SystemUI/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicy.kt
index 22e9487..30b086f 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicy.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/display/StatusBarTouchShadeDisplayPolicy.kt
@@ -22,34 +22,55 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.display.data.repository.DisplayRepository
+import com.android.systemui.keyguard.data.repository.KeyguardRepository
+import com.android.systemui.shade.ShadeOnDefaultDisplayWhenLocked
 import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
 
 /**
  * Moves the shade on the last display that received a status bar touch.
  *
- * If the display is removed, falls back to the default one.
+ * If the display is removed, falls back to the default one. When [shadeOnDefaultDisplayWhenLocked]
+ * is true, the shade falls back to the default display when the keyguard is visible.
  */
 @SysUISingleton
 class StatusBarTouchShadeDisplayPolicy
 @Inject
-constructor(displayRepository: DisplayRepository, @Background val backgroundScope: CoroutineScope) :
-    ShadeDisplayPolicy {
-    override val name: String
-        get() = "status_bar_latest_touch"
+constructor(
+    displayRepository: DisplayRepository,
+    keyguardRepository: KeyguardRepository,
+    @Background val backgroundScope: CoroutineScope,
+    @ShadeOnDefaultDisplayWhenLocked val shadeOnDefaultDisplayWhenLocked: Boolean,
+) : ShadeDisplayPolicy {
+    override val name: String = "status_bar_latest_touch"
 
     private val currentDisplayId = MutableStateFlow(Display.DEFAULT_DISPLAY)
     private val availableDisplayIds: StateFlow<Set<Int>> = displayRepository.displayIds
 
-    override val displayId: StateFlow<Int>
-        get() = currentDisplayId
+    override val displayId: StateFlow<Int> =
+        if (shadeOnDefaultDisplayWhenLocked) {
+            keyguardRepository.isKeyguardShowing
+                .combine(currentDisplayId) { isKeyguardShowing, currentDisplayId ->
+                    if (isKeyguardShowing) {
+                        Display.DEFAULT_DISPLAY
+                    } else {
+                        currentDisplayId
+                    }
+                }
+                .stateIn(backgroundScope, SharingStarted.WhileSubscribed(), currentDisplayId.value)
+        } else {
+            currentDisplayId
+        }
 
     private var removalListener: Job? = null
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
index 3414867..08c03e2 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
@@ -16,10 +16,8 @@
 
 package com.android.systemui.shade.domain.interactor
 
-import android.content.Context
 import android.util.Log
-import android.view.WindowManager
-import android.view.WindowManager.LayoutParams
+import android.window.WindowContext
 import androidx.annotation.UiThread
 import com.android.app.tracing.coroutines.launchTraced
 import com.android.app.tracing.traceSection
@@ -45,9 +43,7 @@
 constructor(
     optionalShadeRootView: Optional<WindowRootView>,
     private val shadePositionRepository: ShadeDisplaysRepository,
-    @ShadeDisplayAware private val shadeContext: Context,
-    @ShadeDisplayAware private val shadeLayoutParams: LayoutParams,
-    @ShadeDisplayAware private val wm: WindowManager,
+    @ShadeDisplayAware private val shadeContext: WindowContext,
     @Background private val bgScope: CoroutineScope,
     @Main private val mainThreadContext: CoroutineContext,
 ) : CoreStartable {
@@ -72,7 +68,11 @@
     /** Tries to move the shade. If anything wrong happens, fails gracefully without crashing. */
     private suspend fun moveShadeWindowTo(destinationId: Int) {
         Log.d(TAG, "Trying to move shade window to display with id $destinationId")
-        val currentDisplay = shadeRootView.display
+        // Why using the shade context here instead of the view's Display?
+        // The context's display is updated before the view one, so it is a better indicator of
+        // which display the shade is supposed to be at. The View display is updated after the first
+        // rendering with the new config.
+        val currentDisplay = shadeContext.display
         if (currentDisplay == null) {
             Log.w(TAG, "Current shade display is null")
             return
@@ -83,7 +83,7 @@
             return
         }
         try {
-            withContext(mainThreadContext) { moveShadeWindow(toId = destinationId) }
+            withContext(mainThreadContext) { reparentToDisplayId(id = destinationId) }
         } catch (e: IllegalStateException) {
             Log.e(
                 TAG,
@@ -94,25 +94,8 @@
     }
 
     @UiThread
-    private fun moveShadeWindow(toId: Int) {
-        traceSection({ "moveShadeWindow  to $toId" }) {
-            removeShadeWindow()
-            updateContextDisplay(toId)
-            addShadeWindow()
-        }
-    }
-
-    @UiThread
-    private fun removeShadeWindow(): Unit =
-        traceSection("removeShadeWindow") { wm.removeView(shadeRootView) }
-
-    @UiThread
-    private fun addShadeWindow(): Unit =
-        traceSection("addShadeWindow") { wm.addView(shadeRootView, shadeLayoutParams) }
-
-    @UiThread
-    private fun updateContextDisplay(newDisplayId: Int) {
-        traceSection("updateContextDisplay") { shadeContext.updateDisplay(newDisplayId) }
+    private fun reparentToDisplayId(id: Int) {
+        traceSection({ "reparentToDisplayId(id=$id)" }) { shadeContext.reparentToDisplay(id) }
     }
 
     private companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
index 6bbd4a5..d343ed5a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
@@ -35,6 +35,7 @@
 import com.android.systemui.dump.DumpManager
 import java.io.PrintWriter
 import javax.inject.Inject
+import com.android.systemui.Flags.notificationShadeBlur
 
 @SysUISingleton
 open class BlurUtils @Inject constructor(
@@ -43,7 +44,14 @@
     dumpManager: DumpManager
 ) : Dumpable {
     val minBlurRadius = resources.getDimensionPixelSize(R.dimen.min_window_blur_radius)
-    val maxBlurRadius = resources.getDimensionPixelSize(R.dimen.max_window_blur_radius)
+    val maxBlurRadius =
+        if (notificationShadeBlur()) {
+            resources.getDimensionPixelSize(R.dimen.max_shade_window_blur_radius)
+        } else {
+            resources.getDimensionPixelSize(R.dimen.max_window_blur_radius)
+        }
+
+
     private var lastAppliedBlur = 0
     private var earlyWakeupEnabled = false
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
index c997ac5..2544323 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
@@ -20,7 +20,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
 
 import static com.android.systemui.Flags.fetchBookmarksXmlKeyboardShortcuts;
-import static com.android.systemui.Flags.validateKeyboardShortcutHelperIconUri;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -78,7 +77,6 @@
 import com.android.internal.app.AssistUtils;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.settingslib.Utils;
 import com.android.systemui.res.R;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 
@@ -428,9 +426,7 @@
                 mKeySearchResultMap.put(SHORTCUT_SPECIFICAPP_INDEX, false);
             } else {
                 mCurrentAppPackageName = result.get(0).getPackageName();
-                if (validateKeyboardShortcutHelperIconUri()) {
-                    KeyboardShortcuts.sanitiseShortcuts(result);
-                }
+                KeyboardShortcuts.sanitiseShortcuts(result);
                 mSpecificAppGroup.addAll(
                         reMapToKeyboardShortcutMultiMappingGroup(result));
                 mKeySearchResultMap.put(SHORTCUT_SPECIFICAPP_INDEX, true);
@@ -446,9 +442,7 @@
         // Add specific Ime shortcuts
         if (result != null) {
             if (!result.isEmpty()) {
-                if (validateKeyboardShortcutHelperIconUri()) {
-                    KeyboardShortcuts.sanitiseShortcuts(result);
-                }
+                KeyboardShortcuts.sanitiseShortcuts(result);
                 mInputGroup.addAll(
                         reMapToKeyboardShortcutMultiMappingGroup(result));
             }
@@ -768,8 +762,6 @@
                     Intent.CATEGORY_APP_EMAIL,
                     Intent.CATEGORY_APP_CALENDAR,
                     Intent.CATEGORY_APP_MAPS,
-                    Intent.CATEGORY_APP_MUSIC,
-                    Intent.CATEGORY_APP_MESSAGING,
                     Intent.CATEGORY_APP_CALCULATOR,
             };
             String[] shortcutLabels = {
@@ -778,19 +770,15 @@
                     mContext.getString(R.string.keyboard_shortcut_group_applications_email),
                     mContext.getString(R.string.keyboard_shortcut_group_applications_calendar),
                     mContext.getString(R.string.keyboard_shortcut_group_applications_maps),
-                    mContext.getString(R.string.keyboard_shortcut_group_applications_music),
-                    mContext.getString(R.string.keyboard_shortcut_group_applications_sms),
                     mContext.getString(R.string.keyboard_shortcut_group_applications_calculator)
             };
 
             int[] keyCodes = {
                 KeyEvent.KEYCODE_B,
-                KeyEvent.KEYCODE_C,
-                KeyEvent.KEYCODE_E,
-                KeyEvent.KEYCODE_K,
-                KeyEvent.KEYCODE_M,
                 KeyEvent.KEYCODE_P,
-                KeyEvent.KEYCODE_S,
+                KeyEvent.KEYCODE_E,
+                KeyEvent.KEYCODE_C,
+                KeyEvent.KEYCODE_M,
                 KeyEvent.KEYCODE_U,
             };
 
@@ -1422,13 +1410,11 @@
     }
 
     private int getColorOfTextColorOnAccent() {
-        return Utils.getColorAttrDefaultColor(
-                mContext, com.android.internal.R.attr.materialColorOnPrimary);
+        return mContext.getColor(com.android.internal.R.color.materialColorOnPrimary);
     }
 
     private int getColorOfTextColorSecondary() {
-        return Utils.getColorAttrDefaultColor(
-                mContext, com.android.internal.R.attr.materialColorOnSurface);
+        return mContext.getColor(com.android.internal.R.color.materialColorOnSurface);
     }
 
     // Create the new data structure for handling the N-to-1 key mapping and other complex case.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
index 766c391..2ed168a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
@@ -21,7 +21,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
 
 import static com.android.systemui.Flags.fetchBookmarksXmlKeyboardShortcuts;
-import static com.android.systemui.Flags.validateKeyboardShortcutHelperIconUri;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -412,10 +411,7 @@
         mReceivedAppShortcutGroups =
                 result == null ? Collections.emptyList() : result;
 
-        if (validateKeyboardShortcutHelperIconUri()) {
-            sanitiseShortcuts(mReceivedAppShortcutGroups);
-        }
-
+        sanitiseShortcuts(mReceivedAppShortcutGroups);
         maybeMergeAndShowKeyboardShortcuts();
     }
 
@@ -423,10 +419,7 @@
         mReceivedImeShortcutGroups =
                 result == null ? Collections.emptyList() : result;
 
-        if (validateKeyboardShortcutHelperIconUri()) {
-            sanitiseShortcuts(mReceivedImeShortcutGroups);
-        }
-
+        sanitiseShortcuts(mReceivedImeShortcutGroups);
         maybeMergeAndShowKeyboardShortcuts();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index 1db7fb4..684466a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -53,6 +53,7 @@
 import javax.inject.Inject
 import kotlin.math.max
 import kotlin.math.sign
+import com.android.systemui.Flags.notificationShadeBlur
 
 /**
  * Responsible for blurring the notification shade window, and applying a zoom effect to the
@@ -220,7 +221,9 @@
 
         // Make blur be 0 if it is necessary to stop blur effect.
         if (scrimsVisible) {
-            blur = 0
+            if (!notificationShadeBlur()) {
+                blur = 0
+            }
             zoomOut = 0f
         }
 
@@ -240,7 +243,7 @@
         Choreographer.FrameCallback {
             updateScheduled = false
             val (blur, zoomOut) = computeBlurAndZoomOut()
-            val opaque = scrimsVisible && !blursDisabledForAppLaunch
+            val opaque = if (notificationShadeBlur()) false else scrimsVisible && !blursDisabledForAppLaunch
             Trace.traceCounter(Trace.TRACE_TAG_APP, "shade_blur_radius", blur)
             blurUtils.applyBlur(root.viewRootImpl, blur, opaque)
             lastAppliedBlur = blur
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt
index 571a3e4..bbecde8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt
@@ -57,6 +57,14 @@
     // top-level tag. It should instead be provided as the first string in each log message.
     private val extraLogTag = "SingleChipInteractor[key=$key]"
 
+    init {
+        if (startingModel.promotedContent == null) {
+            logger.e({ "$str1: Starting model has promotedContent=null, which shouldn't happen" }) {
+                str1 = extraLogTag
+            }
+        }
+    }
+
     private val _notificationModel = MutableStateFlow(startingModel)
 
     /**
@@ -71,6 +79,14 @@
             }
             return
         }
+        if (model.promotedContent == null) {
+            logger.e({
+                "$str1: received model with promotedContent=null, which shouldn't happen"
+            }) {
+                str1 = extraLogTag
+            }
+            return
+        }
         _notificationModel.value = model
     }
 
@@ -99,6 +115,15 @@
         }
 
     private fun ActiveNotificationModel.toNotificationChipModel(): NotificationChipModel? {
+        val promotedContent = this.promotedContent
+        if (promotedContent == null) {
+            logger.w({
+                "$str1: Can't show chip because promotedContent=null, which shouldn't happen"
+            }) {
+                str1 = extraLogTag
+            }
+            return null
+        }
         val statusBarChipIconView = this.statusBarChipIconView
         if (statusBarChipIconView == null) {
             if (!StatusBarConnectedDisplays.isEnabled) {
@@ -111,7 +136,8 @@
                 return null
             }
         }
-        return NotificationChipModel(key, statusBarChipIconView, whenTime)
+
+        return NotificationChipModel(key, statusBarChipIconView, whenTime, promotedContent)
     }
 
     @AssistedFactory
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/model/NotificationChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/model/NotificationChipModel.kt
index 4588b19..9f0638b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/model/NotificationChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/model/NotificationChipModel.kt
@@ -17,10 +17,13 @@
 package com.android.systemui.statusbar.chips.notification.domain.model
 
 import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
 
 /** Modeling all the data needed to render a status bar notification chip. */
 data class NotificationChipModel(
     val key: String,
     val statusBarChipIconView: StatusBarIconView?,
+    // TODO(b/364653005): Use [PromotedNotificationContentModel.time] instead of a custom field.
     val whenTime: Long,
+    val promotedContent: PromotedNotificationContentModel,
 )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
index 2cd5bb3..2d16f3b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
@@ -25,10 +25,12 @@
 import com.android.systemui.statusbar.chips.ui.model.ColorsModel
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
 import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
+import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.launch
 
 /** A view model for status bar chips for promoted ongoing notifications. */
@@ -38,18 +40,24 @@
 constructor(
     @Application private val applicationScope: CoroutineScope,
     private val notifChipsInteractor: StatusBarNotificationChipsInteractor,
+    headsUpNotificationInteractor: HeadsUpNotificationInteractor,
 ) {
     /**
      * A flow modeling the notification chips that should be shown. Emits an empty list if there are
      * no notifications that should show a status bar chip.
      */
     val chips: Flow<List<OngoingActivityChipModel.Shown>> =
-        notifChipsInteractor.notificationChips.map { notifications ->
-            notifications.map { it.toActivityChipModel() }
+        combine(
+            notifChipsInteractor.notificationChips,
+            headsUpNotificationInteractor.statusBarHeadsUpState,
+        ) { notifications, headsUpState ->
+            notifications.map { it.toActivityChipModel(headsUpState) }
         }
 
     /** Converts the notification to the [OngoingActivityChipModel] object. */
-    private fun NotificationChipModel.toActivityChipModel(): OngoingActivityChipModel.Shown {
+    private fun NotificationChipModel.toActivityChipModel(
+        headsUpState: PinnedStatus
+    ): OngoingActivityChipModel.Shown {
         StatusBarNotifChips.assertInNewMode()
         val icon =
             if (this.statusBarChipIconView != null) {
@@ -59,8 +67,11 @@
                 StatusBarConnectedDisplays.assertInNewMode()
                 OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon(this.key)
             }
-        // TODO(b/364653005): Use the notification color if applicable.
-        val colors = ColorsModel.Themed
+        val colors =
+            ColorsModel.Custom(
+                backgroundColorInt = this.promotedContent.colors.backgroundColor,
+                primaryTextColorInt = this.promotedContent.colors.primaryTextColor,
+            )
         val onClickListener =
             View.OnClickListener {
                 // The notification pipeline needs everything to run on the main thread, so keep
@@ -71,12 +82,18 @@
                     )
                 }
             }
-        return OngoingActivityChipModel.Shown.ShortTimeDelta(
-            icon,
-            colors,
-            time = this.whenTime,
-            onClickListener,
-        )
+        return if (headsUpState == PinnedStatus.PinnedByUser) {
+            // If the user tapped the chip to show the HUN, we want to just show the icon because
+            // the HUN will show the rest of the information.
+            OngoingActivityChipModel.Shown.IconOnly(icon, colors, onClickListener)
+        } else {
+            OngoingActivityChipModel.Shown.ShortTimeDelta(
+                icon,
+                colors,
+                time = this.whenTime,
+                onClickListener,
+            )
+        }
         // TODO(b/364653005): Use Notification.showWhen to determine if we should show the time.
         // TODO(b/364653005): If Notification.shortCriticalText is set, use that instead of `when`.
         // TODO(b/364653005): If the app that posted the notification is in the foreground, don't
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt
index 4b0fc5a..efedf41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt
@@ -40,21 +40,25 @@
     }
 
     /**
-     * The chip should have the given background color, and text color that matches dark/light
-     * theme.
+     * The chip should have the given background color and primary text color.
+     *
+     * If [primaryTextColorInt] is null, the text color will match the current UI mode (light/dark).
      */
-    data class Custom(val backgroundColorInt: Int) : ColorsModel {
+    data class Custom(val backgroundColorInt: Int, val primaryTextColorInt: Int? = null) :
+        ColorsModel {
         override fun background(context: Context): ColorStateList =
             ColorStateList.valueOf(backgroundColorInt)
 
-        // TODO(b/361346412): When dark theme changes, the chip should automatically re-render with
+        // TODO(b/361346412): When UI mode changes, the chip should automatically re-render with
         // the right text color. Right now, it has the right text color when the chip is first
-        // created but the color doesn't update if dark theme changes.
-        override fun text(context: Context) =
-            Utils.getColorAttrDefaultColor(
-                context,
-                com.android.internal.R.attr.materialColorOnSurface,
-            )
+        // created but the color doesn't update if UI mode changes.
+        override fun text(context: Context): Int {
+            return primaryTextColorInt
+                ?: Utils.getColorAttrDefaultColor(
+                    context,
+                    com.android.internal.R.color.materialColorOnSurface,
+                )
+        }
     }
 
     /** The chip should have a red background with white text. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt
index 280d66b..6cf2c73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt
@@ -18,9 +18,9 @@
 
 import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR
 import com.android.systemui.CoreStartable
-import com.android.systemui.common.ui.GlobalConfig
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.display.data.repository.DisplayRepository
 import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
 import com.android.systemui.display.data.repository.PerDisplayStore
@@ -74,7 +74,7 @@
 @SysUISingleton
 class SingleDisplayStatusBarConfigurationControllerStore
 @Inject
-constructor(@GlobalConfig globalConfigurationController: ConfigurationController) :
+constructor(@Main globalConfigurationController: ConfigurationController) :
     StatusBarConfigurationControllerStore,
     PerDisplayStore<StatusBarConfigurationController> by SingleDisplayStore(
         globalConfigurationController as StatusBarConfigurationController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarModePerDisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarModePerDisplayRepository.kt
index cc91e2d..22c37df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarModePerDisplayRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarModePerDisplayRepository.kt
@@ -37,6 +37,7 @@
 import com.android.systemui.statusbar.phone.LetterboxAppearanceCalculator
 import com.android.systemui.statusbar.phone.StatusBarBoundsProvider
 import com.android.systemui.statusbar.phone.fragment.dagger.HomeStatusBarComponent
+import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
 import com.android.systemui.statusbar.phone.ongoingcall.data.repository.OngoingCallRepository
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
 import dagger.assisted.Assisted
@@ -89,6 +90,9 @@
     /** The current mode of the status bar. */
     val statusBarMode: StateFlow<StatusBarMode>
 
+    /** Whether the status bar is forced to be visible because of an ongoing call */
+    val ongoingProcessRequiresStatusBarVisible: StateFlow<Boolean>
+
     /**
      * Requests for the status bar to be shown transiently.
      *
@@ -110,6 +114,12 @@
      * if needed.
      */
     fun stop()
+
+    /**
+     * Called when an ongoing process needs to prevent the status bar from being hidden in any
+     * state.
+     */
+    fun setOngoingProcessRequiresStatusBarVisible(requiredVisible: Boolean)
 }
 
 class StatusBarModePerDisplayRepositoryImpl
@@ -195,6 +205,16 @@
         statusBarBoundsProvider.addChangeListener(listener)
     }
 
+    private val _ongoingProcessRequiresStatusBarVisible = MutableStateFlow(false)
+    override val ongoingProcessRequiresStatusBarVisible =
+        _ongoingProcessRequiresStatusBarVisible.asStateFlow()
+
+    override fun setOngoingProcessRequiresStatusBarVisible(
+        requiredVisible: Boolean
+    ) {
+        _ongoingProcessRequiresStatusBarVisible.value = requiredVisible
+    }
+
     override val isInFullscreenMode: StateFlow<Boolean> =
         _originalStatusBarAttributes
             .map { params ->
@@ -235,16 +255,28 @@
                 isTransientShown,
                 isInFullscreenMode,
                 ongoingCallRepository.ongoingCallState,
-            ) { modifiedAttributes, isTransientShown, isInFullscreenMode, ongoingCallState ->
+                _ongoingProcessRequiresStatusBarVisible,
+            ) {
+                modifiedAttributes,
+                isTransientShown,
+                isInFullscreenMode,
+                ongoingCallStateLegacy,
+                ongoingProcessRequiresStatusBarVisible ->
                 if (modifiedAttributes == null) {
                     null
                 } else {
+                    val hasOngoingCall =
+                        if (StatusBarChipsModernization.isEnabled) {
+                            ongoingProcessRequiresStatusBarVisible
+                        } else {
+                            ongoingCallStateLegacy is OngoingCallModel.InCall
+                        }
                     val statusBarMode =
                         toBarMode(
                             modifiedAttributes.appearance,
                             isTransientShown,
                             isInFullscreenMode,
-                            hasOngoingCall = ongoingCallState is OngoingCallModel.InCall,
+                            hasOngoingCall,
                         )
                     StatusBarAppearance(
                         statusBarMode,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index 6b84b6d..c38b84b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -666,7 +666,16 @@
     }
 
     public boolean isRowPinned() {
-        return row != null && row.isPinned();
+        return getPinnedStatus().isPinned();
+    }
+
+    /** Returns this notification's current pinned status. */
+    public PinnedStatus getPinnedStatus() {
+        if (row != null) {
+            return row.getPinnedStatus();
+        } else {
+            return PinnedStatus.NotPinned;
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
index 0269b16..eb6ec9f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
@@ -43,6 +43,7 @@
 import com.android.systemui.statusbar.notification.dagger.IncomingHeader
 import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.notification.headsup.OnHeadsUpChangedListener
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus
 import com.android.systemui.statusbar.notification.interruption.HeadsUpViewBinder
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider
 import com.android.systemui.statusbar.notification.logKey
@@ -145,6 +146,7 @@
                 // heads-up is considered to be the top notification.
                 shouldHeadsUpEver = true,
                 shouldHeadsUpAgain = true,
+                isPinnedByUser = true,
                 isHeadsUpEntry = mHeadsUpManager.isHeadsUpEntry(entry.key),
                 isBinding = isEntryBinding(entry),
             )
@@ -155,8 +157,8 @@
         }
     }
 
-    private fun onHeadsUpViewBound(entry: NotificationEntry) {
-        mHeadsUpManager.showNotification(entry)
+    private fun onHeadsUpViewBound(entry: NotificationEntry, isPinnedByUser: Boolean) {
+        mHeadsUpManager.showNotification(entry, isPinnedByUser)
         mEntriesBindingUntil.remove(entry.key)
     }
 
@@ -424,6 +426,7 @@
 
     private fun handlePostedEntry(posted: PostedEntry, hunMutator: HunMutator, scenario: String) {
         mLogger.logPostedEntryWillEvaluate(posted, scenario)
+
         if (posted.wasAdded) {
             if (posted.shouldHeadsUpEver) {
                 bindForAsyncHeadsUp(posted)
@@ -437,7 +440,17 @@
                     // If showing heads up, we need to post an update. Otherwise we're still
                     // binding, and we can just let that finish.
                     if (posted.isHeadsUpEntry) {
-                        hunMutator.updateNotification(posted.key, posted.shouldHeadsUpAgain)
+                        val pinnedStatus =
+                            if (posted.shouldHeadsUpAgain) {
+                                if (StatusBarNotifChips.isEnabled && posted.isPinnedByUser) {
+                                    PinnedStatus.PinnedByUser
+                                } else {
+                                    PinnedStatus.PinnedBySystem
+                                }
+                            } else {
+                                PinnedStatus.NotPinned
+                            }
+                        hunMutator.updateNotification(posted.key, pinnedStatus)
                     }
                 } else {
                     if (posted.isHeadsUpEntry) {
@@ -461,10 +474,11 @@
     }
 
     private fun bindForAsyncHeadsUp(posted: PostedEntry) {
+        val isPinnedByUser = StatusBarNotifChips.isEnabled && posted.isPinnedByUser
         // TODO: Add a guarantee to bindHeadsUpView of some kind of callback if the bind is
         //  cancelled so that we don't need to have this sad timeout hack.
         mEntriesBindingUntil[posted.key] = mNow + BIND_TIMEOUT
-        mHeadsUpViewBinder.bindHeadsUpView(posted.entry, this::onHeadsUpViewBound)
+        mHeadsUpViewBinder.bindHeadsUpView(posted.entry, isPinnedByUser, this::onHeadsUpViewBound)
     }
 
     private val mNotifCollectionListener =
@@ -906,6 +920,7 @@
         var wasUpdated: Boolean,
         var shouldHeadsUpEver: Boolean,
         var shouldHeadsUpAgain: Boolean,
+        var isPinnedByUser: Boolean = false,
         var isHeadsUpEntry: Boolean,
         var isBinding: Boolean,
     ) {
@@ -943,7 +958,7 @@
 
 /** Mutates the HeadsUp state of notifications. */
 private interface HunMutator {
-    fun updateNotification(key: String, shouldHeadsUpAgain: Boolean)
+    fun updateNotification(key: String, requestedPinnedStatus: PinnedStatus)
 
     fun removeNotification(key: String, releaseImmediately: Boolean)
 }
@@ -955,8 +970,8 @@
 private class HunMutatorImpl(private val headsUpManager: HeadsUpManager) : HunMutator {
     private val deferred = mutableListOf<Pair<String, Boolean>>()
 
-    override fun updateNotification(key: String, shouldHeadsUpAgain: Boolean) {
-        headsUpManager.updateNotification(key, shouldHeadsUpAgain)
+    override fun updateNotification(key: String, requestedPinnedStatus: PinnedStatus) {
+        headsUpManager.updateNotification(key, requestedPinnedStatus)
     }
 
     override fun removeNotification(key: String, releaseImmediately: Boolean) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
index ef7b1c3..04458f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
@@ -14,10 +14,13 @@
  * limitations under the License.
  */
 
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
 package com.android.systemui.statusbar.notification.collection.coordinator
 
 import android.app.Notification
 import android.os.UserHandle
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.server.notification.Flags.screenshareNotificationHiding
 import com.android.systemui.dagger.qualifiers.Application
@@ -44,9 +47,9 @@
 import dagger.Module
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.mapNotNull
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 @Module(includes = [PrivateSensitiveContentCoordinatorModule::class])
 interface SensitiveContentCoordinatorModule
@@ -80,6 +83,7 @@
     DynamicPrivacyController.Listener,
     OnBeforeRenderListListener {
     private var inTransitionFromLockedToGone = false
+    private var canSwipeToEnter = false
 
     private val onSensitiveStateChanged = Runnable() { invalidateList("onSensitiveStateChanged") }
 
@@ -98,7 +102,9 @@
         }
 
     override fun attach(pipeline: NotifPipeline) {
-        dynamicPrivacyController.addListener(this)
+        if (!SceneContainerFlag.isEnabled) {
+            dynamicPrivacyController.addListener(this)
+        }
         if (screenshareNotificationHiding()) {
             sensitiveNotificationProtectionController.registerSensitiveStateListener(
                 onSensitiveStateChanged
@@ -128,6 +134,15 @@
                         invalidateList("inTransitionFromLockedToGoneChanged")
                     }
             }
+            scope.launch {
+                deviceEntryInteractor.canSwipeToEnter.collect {
+                    val canSwipeToEnter = it ?: false
+                    if (this@SensitiveContentCoordinatorImpl.canSwipeToEnter != canSwipeToEnter) {
+                        this@SensitiveContentCoordinatorImpl.canSwipeToEnter = canSwipeToEnter
+                        invalidateList("canSwipeToEnterChanged")
+                    }
+                }
+            }
         }
     }
 
@@ -168,7 +183,9 @@
             (devicePublic &&
                 !lockscreenUserManager.userAllowsPrivateNotificationsInPublic(currentUserId)) ||
                 isSensitiveContentProtectionActive
-        val dynamicallyUnlocked = dynamicPrivacyController.isDynamicallyUnlocked
+        val dynamicallyUnlocked =
+            if (SceneContainerFlag.isEnabled) canSwipeToEnter
+            else dynamicPrivacyController.isDynamicallyUnlocked
         for (entry in extractAllRepresentativeEntries(entries).filter { it.rowExists() }) {
             val notifUserId = entry.sbn.user.identifier
             val userLockscreen =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
index 64e78e4..75c7d2d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.statusbar.notification.data.repository.HeadsUpRepository
 import com.android.systemui.statusbar.notification.data.repository.HeadsUpRowRepository
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus
 import com.android.systemui.statusbar.notification.shared.HeadsUpRowKey
 import javax.inject.Inject
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -97,19 +98,22 @@
         }
     }
 
-    /** Are there any pinned heads up rows to display? */
-    val hasPinnedRows: Flow<Boolean> =
+    /** What [PinnedStatus] does the top row have? */
+    private val topPinnedStatus: Flow<PinnedStatus> =
         headsUpRepository.activeHeadsUpRows.flatMapLatest { rows ->
             if (rows.isNotEmpty()) {
                 combine(rows.map { it.pinnedStatus }) { pinnedStatus ->
-                    pinnedStatus.any { it.isPinned }
+                    pinnedStatus.firstOrNull { it.isPinned } ?: PinnedStatus.NotPinned
                 }
             } else {
                 // if the set is empty, there are no flows to combine
-                flowOf(false)
+                flowOf(PinnedStatus.NotPinned)
             }
         }
 
+    /** Are there any pinned heads up rows to display? */
+    val hasPinnedRows: Flow<Boolean> = topPinnedStatus.map { it.isPinned }
+
     val isHeadsUpOrAnimatingAway: Flow<Boolean> by lazy {
         if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) {
             flowOf(false)
@@ -138,9 +142,14 @@
             }
         }
 
-    val showHeadsUpStatusBar =
-        combine(hasPinnedRows, canShowHeadsUp) { hasPinnedRows, canShowHeadsUp ->
-            hasPinnedRows && canShowHeadsUp
+    /** Emits the pinned notification state as it relates to the status bar. */
+    val statusBarHeadsUpState: Flow<PinnedStatus> =
+        combine(topPinnedStatus, canShowHeadsUp) { topPinnedStatus, canShowHeadsUp ->
+            if (canShowHeadsUp) {
+                topPinnedStatus
+            } else {
+                PinnedStatus.NotPinned
+            }
         }
 
     fun headsUpRow(key: HeadsUpRowKey): HeadsUpRowInteractor =
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 a0515ca..d258898 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
@@ -39,7 +39,6 @@
 
 import androidx.annotation.NonNull;
 
-import com.android.settingslib.Utils;
 import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.ColorUpdateLogger;
 import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefactor;
@@ -457,8 +456,8 @@
      */
     public void updateColors() {
         Resources.Theme theme = mContext.getTheme();
-        final @ColorInt int onSurface = Utils.getColorAttrDefaultColor(mContext,
-                com.android.internal.R.attr.materialColorOnSurface);
+        final @ColorInt int onSurface = mContext.getColor(
+                com.android.internal.R.color.materialColorOnSurface);
         // Same resource, separate drawables to prevent touch effects from showing on the wrong
         // button.
         final Drawable clearAllBg = theme.getDrawable(R.drawable.notif_footer_btn_background);
@@ -467,8 +466,8 @@
                 ? theme.getDrawable(R.drawable.notif_footer_btn_background) : null;
         final @ColorInt int scHigh;
         if (!notificationFooterBackgroundTintOptimization()) {
-            scHigh = Utils.getColorAttrDefaultColor(mContext,
-                    com.android.internal.R.attr.materialColorSurfaceContainerHigh);
+            scHigh = mContext.getColor(
+                    com.android.internal.R.color.materialColorSurfaceContainerHigh);
             if (scHigh != 0) {
                 final ColorFilter bgColorFilter = new PorterDuffColorFilter(scHigh, SRC_ATOP);
                 clearAllBg.setColorFilter(bgColorFilter);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManager.kt
index 424a3c5..95234da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManager.kt
@@ -88,6 +88,12 @@
     /** Returns whether there are any pinned Heads Up Notifications or not. */
     fun hasPinnedHeadsUp(): Boolean
 
+    /**
+     * Returns the status of the top Heads Up Notification, or returns [PinnedStatus.NotPinned] if
+     * there is no pinned HUN.
+     */
+    fun pinnedHeadsUpStatus(): PinnedStatus
+
     /** Returns whether or not the given notification is managed by this manager. */
     fun isHeadsUpEntry(key: String): Boolean
 
@@ -204,8 +210,10 @@
      * the notification to be managed.
      *
      * @param entry entry to show
+     * @param isPinnedByUser true if the notification was pinned by the user and false if the
+     *   notification was pinned by the system.
      */
-    fun showNotification(entry: NotificationEntry)
+    fun showNotification(entry: NotificationEntry, isPinnedByUser: Boolean = false)
 
     fun snooze()
 
@@ -216,7 +224,15 @@
      */
     fun unpinAll(userUnPinned: Boolean)
 
-    fun updateNotification(key: String, shouldHeadsUpAgain: Boolean)
+    /**
+     * Called when the notification state has been updated.
+     *
+     * @param key the key of the entry that was updated
+     * @param requestedPinnedStatus whether and how the notification should be pinned. If equal to
+     *   [PinnedStatus.NotPinned], the notification won't show again. Otherwise, the notification
+     *   should show again and will force reevaluation of removal time.
+     */
+    fun updateNotification(key: String, requestedPinnedStatus: PinnedStatus)
 
     fun onEntryAnimatingAwayEnded(entry: NotificationEntry)
 }
@@ -262,6 +278,8 @@
 
     override fun hasPinnedHeadsUp() = false
 
+    override fun pinnedHeadsUpStatus() = PinnedStatus.NotPinned
+
     override fun isHeadsUpEntry(key: String) = false
 
     override fun isHeadsUpAnimatingAwayValue() = false
@@ -306,13 +324,13 @@
 
     override fun shouldSwallowClick(key: String): Boolean = false
 
-    override fun showNotification(entry: NotificationEntry) {}
+    override fun showNotification(entry: NotificationEntry, isPinnedByUser: Boolean) {}
 
     override fun snooze() {}
 
     override fun unpinAll(userUnPinned: Boolean) {}
 
-    override fun updateNotification(key: String, alert: Boolean) {}
+    override fun updateNotification(key: String, requestedPinnedStatus: PinnedStatus) {}
 
     override fun onEntryAnimatingAwayEnded(entry: NotificationEntry) {}
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java
index 0b188afa..6aa8d0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java
@@ -45,6 +45,7 @@
 import com.android.systemui.shade.ShadeDisplayAware;
 import com.android.systemui.shade.domain.interactor.ShadeInteractor;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener;
 import com.android.systemui.statusbar.notification.collection.provider.OnReorderingBannedListener;
@@ -99,6 +100,7 @@
     protected int mTouchAcceptanceDelay;
     protected int mSnoozeLengthMs;
     protected boolean mHasPinnedNotification;
+    private PinnedStatus mPinnedNotificationStatus = PinnedStatus.NotPinned;
     protected int mUser;
 
     private final ArrayMap<String, Long> mSnoozedPackages;
@@ -183,7 +185,7 @@
 
     @Inject
     public HeadsUpManagerImpl(
-            @NonNull final Context context,
+            @NonNull @ShadeDisplayAware final Context context,
             HeadsUpManagerLogger logger,
             StatusBarStateController statusBarStateController,
             KeyguardBypassController bypassController,
@@ -303,28 +305,28 @@
                 + resources.getDimensionPixelSize(R.dimen.heads_up_status_bar_padding);
     }
 
-    /**
-     * Called when posting a new notification that should appear on screen.
-     * Adds the notification to be managed.
-     * @param entry entry to show
-     */
     @Override
-    public void showNotification(@NonNull NotificationEntry entry) {
+    public void showNotification(
+            @NonNull NotificationEntry entry, boolean isPinnedByUser) {
         HeadsUpEntry headsUpEntry = createHeadsUpEntry(entry);
 
-        mLogger.logShowNotificationRequest(entry);
+        mLogger.logShowNotificationRequest(entry, isPinnedByUser);
 
         Runnable runnable = () -> {
-            mLogger.logShowNotification(entry);
+            mLogger.logShowNotification(entry, isPinnedByUser);
 
             // Add new entry and begin managing it
             mHeadsUpEntryMap.put(entry.getKey(), headsUpEntry);
-            onEntryAdded(headsUpEntry);
+            PinnedStatus requestedPinnedStatus =
+                    isPinnedByUser
+                            ? PinnedStatus.PinnedByUser
+                            : PinnedStatus.PinnedBySystem;
+            onEntryAdded(headsUpEntry, requestedPinnedStatus);
             // TODO(b/328390331) move accessibility events to the view layer
             entry.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
             entry.setIsHeadsUpEntry(true);
 
-            updateNotificationInternal(entry.getKey(), true /* shouldHeadsUpAgain */);
+            updateNotificationInternal(entry.getKey(), requestedPinnedStatus);
             entry.setInterruption();
         };
         mAvalancheController.update(headsUpEntry, runnable, "showNotification");
@@ -375,25 +377,22 @@
         return false;
     }
 
-    /**
-     * Called when the notification state has been updated.
-     * @param key the key of the entry that was updated
-     * @param shouldHeadsUpAgain whether the notification should show again and force reevaluation
-     *                           of removal time
-     */
-    public void updateNotification(@NonNull String key, boolean shouldHeadsUpAgain) {
+    @Override
+    public void updateNotification(
+            @NonNull String key, @NonNull PinnedStatus requestedPinnedStatus) {
         HeadsUpEntry headsUpEntry = mHeadsUpEntryMap.get(key);
-        mLogger.logUpdateNotificationRequest(key, shouldHeadsUpAgain, headsUpEntry != null);
+        mLogger.logUpdateNotificationRequest(key, requestedPinnedStatus, headsUpEntry != null);
 
         Runnable runnable = () -> {
-            updateNotificationInternal(key, shouldHeadsUpAgain);
+            updateNotificationInternal(key, requestedPinnedStatus);
         };
         mAvalancheController.update(headsUpEntry, runnable, "updateNotification");
     }
 
-    private void updateNotificationInternal(@NonNull String key, boolean shouldHeadsUpAgain) {
+    private void updateNotificationInternal(
+            @NonNull String key, PinnedStatus requestedPinnedStatus) {
         HeadsUpEntry headsUpEntry = mHeadsUpEntryMap.get(key);
-        mLogger.logUpdateNotification(key, shouldHeadsUpAgain, headsUpEntry != null);
+        mLogger.logUpdateNotification(key, requestedPinnedStatus, headsUpEntry != null);
         if (headsUpEntry == null) {
             // the entry was released before this update (i.e by a listener) This can happen
             // with the groupmanager
@@ -404,11 +403,10 @@
             headsUpEntry.mEntry.sendAccessibilityEvent(
                     AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
         }
-        if (shouldHeadsUpAgain) {
+        if (requestedPinnedStatus.isPinned()) {
             headsUpEntry.updateEntry(true /* updatePostTime */, "updateNotification");
-            PinnedStatus pinnedStatus = shouldHeadsUpBecomePinned(headsUpEntry.mEntry)
-                    ? PinnedStatus.PinnedBySystem
-                    : PinnedStatus.NotPinned;
+            PinnedStatus pinnedStatus =
+                    getNewPinnedStatusForEntry(headsUpEntry, requestedPinnedStatus);
             if (headsUpEntry != null) {
                 setEntryPinned(headsUpEntry, pinnedStatus, "updateNotificationInternal");
             }
@@ -596,22 +594,43 @@
      * Manager-specific logic that should occur when an entry is added.
      * @param headsUpEntry entry added
      */
-    protected void onEntryAdded(HeadsUpEntry headsUpEntry) {
+    @VisibleForTesting
+    void onEntryAdded(HeadsUpEntry headsUpEntry, PinnedStatus requestedPinnedStatus) {
         NotificationEntry entry = headsUpEntry.mEntry;
         entry.setHeadsUp(true);
 
-        final PinnedStatus pinnedStatus = shouldHeadsUpBecomePinned(entry)
-                ? PinnedStatus.PinnedBySystem
-                : PinnedStatus.NotPinned;
+        PinnedStatus pinnedStatus = getNewPinnedStatusForEntry(headsUpEntry, requestedPinnedStatus);
         setEntryPinned(headsUpEntry, pinnedStatus, "onEntryAdded");
         EventLogTags.writeSysuiHeadsUpStatus(entry.getKey(), 1 /* visible */);
         for (OnHeadsUpChangedListener listener : mListeners) {
+            // TODO(b/382509804): It's odd that if pinnedStatus == PinnedStatus.NotPinned, then we
+            //  still send isHeadsUp=true to listeners. Is this causing bugs?
             listener.onHeadsUpStateChanged(entry, true);
         }
         updateTopHeadsUpFlow();
         updateHeadsUpFlow();
     }
 
+    private PinnedStatus getNewPinnedStatusForEntry(
+            HeadsUpEntry headsUpEntry, PinnedStatus requestedPinnedStatus) {
+        NotificationEntry entry = headsUpEntry.mEntry;
+        if (entry == null) {
+            return PinnedStatus.NotPinned;
+        }
+        boolean shouldBecomePinned = shouldHeadsUpBecomePinned(entry);
+        if (!shouldBecomePinned) {
+            return PinnedStatus.NotPinned;
+        }
+
+        if (!StatusBarNotifChips.isEnabled()
+                && requestedPinnedStatus == PinnedStatus.PinnedByUser) {
+            Log.wtf(TAG, "PinnedStatus.PinnedByUser not allowed if StatusBarNotifChips flag off");
+            return PinnedStatus.NotPinned;
+        }
+
+        return requestedPinnedStatus;
+    }
+
     /**
      * Remove a notification from the alerting entries.
      * @param key key of notification to remove
@@ -747,10 +766,11 @@
 
     protected void updatePinnedMode() {
         boolean hasPinnedNotification = hasPinnedNotificationInternal();
+        mPinnedNotificationStatus = pinnedNotificationStatusInternal();
         if (hasPinnedNotification == mHasPinnedNotification) {
             return;
         }
-        mLogger.logUpdatePinnedMode(hasPinnedNotification);
+        mLogger.logUpdatePinnedMode(hasPinnedNotification, mPinnedNotificationStatus);
         mHasPinnedNotification = hasPinnedNotification;
         if (mHasPinnedNotification) {
             MetricsLogger.count(mContext, "note_peek", 1);
@@ -941,13 +961,20 @@
         pw.println(mTouchableRegion);
     }
 
-    /**
-     * Returns if there are any pinned Heads Up Notifications or not.
-     */
+    @Override
     public boolean hasPinnedHeadsUp() {
         return mHasPinnedNotification;
     }
 
+    @Override
+    @NonNull
+    public PinnedStatus pinnedHeadsUpStatus() {
+        if (!StatusBarNotifChips.isEnabled()) {
+            return mHasPinnedNotification ? PinnedStatus.PinnedBySystem : PinnedStatus.NotPinned;
+        }
+        return mPinnedNotificationStatus;
+    }
+
     private boolean hasPinnedNotificationInternal() {
         for (String key : mHeadsUpEntryMap.keySet()) {
             HeadsUpEntry entry = getHeadsUpEntry(key);
@@ -958,6 +985,16 @@
         return false;
     }
 
+    private PinnedStatus pinnedNotificationStatusInternal() {
+        for (String key : mHeadsUpEntryMap.keySet()) {
+            HeadsUpEntry entry = getHeadsUpEntry(key);
+            if (entry.mEntry != null && entry.mEntry.isRowPinned()) {
+                return entry.mEntry.getPinnedStatus();
+            }
+        }
+        return PinnedStatus.NotPinned;
+    }
+
     /**
      * Unpins all pinned Heads Up Notifications.
      * @param userUnPinned The unpinned action is trigger by user real operation.
@@ -1305,10 +1342,6 @@
             }
         }
 
-        protected boolean isRowPinned() {
-            return mEntry != null && mEntry.isRowPinned();
-        }
-
         protected void setRowPinnedStatus(PinnedStatus pinnedStatus) {
             if (mEntry != null) mEntry.setRowPinnedStatus(pinnedStatus);
             mPinnedStatus.setValue(pinnedStatus);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerLogger.kt
index 80225c4..1ccc45b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerLogger.kt
@@ -44,8 +44,16 @@
         buffer.log(TAG, INFO, {}, { "release all immediately" })
     }
 
-    fun logShowNotificationRequest(entry: NotificationEntry) {
-        buffer.log(TAG, INFO, { str1 = entry.logKey }, { "request: show notification $str1" })
+    fun logShowNotificationRequest(entry: NotificationEntry, isPinnedByUser: Boolean) {
+        buffer.log(
+            TAG,
+            INFO,
+            {
+                str1 = entry.logKey
+                bool1 = isPinnedByUser
+            },
+            { "request: show notification $str1. isPinnedByUser=$bool1" },
+        )
     }
 
     fun logAvalancheUpdate(
@@ -86,8 +94,16 @@
         )
     }
 
-    fun logShowNotification(entry: NotificationEntry) {
-        buffer.log(TAG, INFO, { str1 = entry.logKey }, { "show notification $str1" })
+    fun logShowNotification(entry: NotificationEntry, isPinnedByUser: Boolean) {
+        buffer.log(
+            TAG,
+            INFO,
+            {
+                str1 = entry.logKey
+                bool1 = isPinnedByUser
+            },
+            { "show notification $str1. isPinnedByUser=$bool1" },
+        )
     }
 
     fun logAutoRemoveScheduled(entry: NotificationEntry, delayMillis: Long, reason: String) {
@@ -224,29 +240,33 @@
         buffer.log(TAG, INFO, { str1 = entry.logKey }, { "notification removed $str1 " })
     }
 
-    fun logUpdateNotificationRequest(key: String, alert: Boolean, hasEntry: Boolean) {
+    fun logUpdateNotificationRequest(
+        key: String,
+        requestedPinnedStatus: PinnedStatus,
+        hasEntry: Boolean,
+    ) {
         buffer.log(
             TAG,
             INFO,
             {
                 str1 = logKey(key)
-                bool1 = alert
-                bool2 = hasEntry
+                bool1 = hasEntry
+                str2 = requestedPinnedStatus.name
             },
-            { "request: update notification $str1 alert: $bool1 hasEntry: $bool2" },
+            { "request: update notification $str1. hasEntry: $bool1. requestedPinnedStatus: $str2" },
         )
     }
 
-    fun logUpdateNotification(key: String, alert: Boolean, hasEntry: Boolean) {
+    fun logUpdateNotification(key: String, requestedPinnedStatus: PinnedStatus, hasEntry: Boolean) {
         buffer.log(
             TAG,
             INFO,
             {
                 str1 = logKey(key)
-                bool1 = alert
-                bool2 = hasEntry
+                bool1 = hasEntry
+                str2 = requestedPinnedStatus.name
             },
-            { "update notification $str1 alert: $bool1 hasEntry: $bool2" },
+            { "update notification $str1. hasEntry: $bool2. requestedPinnedStatus: $str2" },
         )
     }
 
@@ -285,12 +305,18 @@
         )
     }
 
-    fun logUpdatePinnedMode(hasPinnedNotification: Boolean) {
+    fun logUpdatePinnedMode(
+        hasPinnedNotification: Boolean,
+        pinnedNotificationStatus: PinnedStatus,
+    ) {
         buffer.log(
             TAG,
             INFO,
-            { bool1 = hasPinnedNotification },
-            { "has pinned notification changed to $bool1" },
+            {
+                bool1 = hasPinnedNotification
+                str1 = pinnedNotificationStatus.name
+            },
+            { "has pinned notification changed to $bool1, status=$str1" },
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconBuilder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconBuilder.kt
index 0f19d72..9dc3ed2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconBuilder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconBuilder.kt
@@ -18,13 +18,14 @@
 
 import android.app.Notification
 import android.content.Context
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.statusbar.StatusBarIconView
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.contentDescForNotification
 import javax.inject.Inject
 
 /** Testable wrapper around Context. */
-class IconBuilder @Inject constructor(private val context: Context) {
+class IconBuilder @Inject constructor(@Main private val context: Context) {
     @JvmOverloads
     fun createIconView(
         entry: NotificationEntry,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
index 6dbb714..643ee24 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
@@ -16,7 +16,6 @@
 package com.android.systemui.statusbar.notification.icon.ui.viewbinder
 
 import android.graphics.Color
-import android.graphics.Rect
 import android.util.Log
 import android.view.View
 import android.view.ViewGroup
@@ -53,7 +52,6 @@
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.mapNotNull
 import kotlinx.coroutines.flow.stateIn
 
 /** Binds a view-model to a [NotificationIconContainer]. */
@@ -71,10 +69,7 @@
         launch {
             val contrastColorUtil = ContrastColorUtil.getInstance(view.context)
             val iconColors: StateFlow<NotificationIconColors> =
-                viewModel
-                    .iconColors(displayId)
-                    .mapNotNull { it.iconColors(view.viewBounds) }
-                    .stateIn(this)
+                viewModel.iconColors(displayId).stateIn(this)
             viewModel.icons.bindIcons(
                 logTag = "statusbar",
                 view = view,
@@ -374,18 +369,6 @@
         getEntry(key)?.icons?.let(block)
     }
 
-private val View.viewBounds: Rect
-    get() {
-        val tmpArray = intArrayOf(0, 0)
-        getLocationOnScreen(tmpArray)
-        return Rect(
-            /* left = */ tmpArray[0],
-            /* top = */ tmpArray[1],
-            /* right = */ left + width,
-            /* bottom = */ top + height,
-        )
-    }
-
 private suspend inline fun <T> Flow<T>.collectTracingEach(
     tag: String,
     crossinline collector: (T) -> Unit,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/StatusBarIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/StatusBarIconViewBinder.kt
index 83f56a0..124bd2ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/StatusBarIconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/StatusBarIconViewBinder.kt
@@ -16,8 +16,6 @@
 
 package com.android.systemui.statusbar.notification.icon.ui.viewbinder
 
-import android.graphics.Rect
-import android.view.View
 import com.android.app.tracing.traceSection
 import com.android.internal.util.ContrastColorUtil
 import com.android.systemui.res.R
@@ -25,6 +23,7 @@
 import com.android.systemui.statusbar.StatusBarIconView.NO_COLOR
 import com.android.systemui.statusbar.notification.NotificationUtils
 import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconColors
+import com.android.systemui.util.view.viewBoundsOnScreen
 import kotlinx.coroutines.flow.Flow
 
 object StatusBarIconViewBinder {
@@ -60,25 +59,13 @@
             val isPreL = java.lang.Boolean.TRUE == view.getTag(R.id.icon_is_pre_L)
             val isColorized = !isPreL || NotificationUtils.isGrayscale(view, contrastColorUtil)
             view.staticDrawableColor =
-                if (isColorized) colors.staticDrawableColor(view.viewBounds) else NO_COLOR
+                if (isColorized) colors.staticDrawableColor(view.viewBoundsOnScreen()) else NO_COLOR
             // Set the color for the overflow dot
             view.setDecorColor(colors.tint)
         }
     }
 }
 
-private val View.viewBounds: Rect
-    get() {
-        val tmpArray = intArrayOf(0, 0)
-        getLocationOnScreen(tmpArray)
-        return Rect(
-            /* left = */ tmpArray[0],
-            /* top = */ tmpArray[1],
-            /* right = */ left + width,
-            /* bottom = */ top + height,
-        )
-    }
-
 private suspend inline fun <T> Flow<T>.collectTracingEach(
     tag: String,
     crossinline collector: (T) -> Unit,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconColors.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconColors.kt
index 2365db4..a9635dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconColors.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconColors.kt
@@ -17,14 +17,6 @@
 
 import android.graphics.Rect
 
-/**
- * Lookup the colors to use for the notification icons based on the bounds of the icon container. A
- * result of `null` indicates that no color changes should be applied.
- */
-fun interface NotificationIconColorLookup {
-    fun iconColors(viewBounds: Rect): NotificationIconColors?
-}
-
 /** Colors to apply to notification icons. */
 interface NotificationIconColors {
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
index f0b0306..2ba28a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
@@ -68,18 +68,10 @@
             .distinctUntilChanged()
 
     /** The colors with which to display the notification icons. */
-    fun iconColors(displayId: Int): Flow<NotificationIconColorLookup> =
+    fun iconColors(displayId: Int): Flow<NotificationIconColors> =
         darkIconInteractor
             .darkState(displayId)
-            .map { (areas: Collection<Rect>, tint: Int) ->
-                NotificationIconColorLookup { viewBounds: Rect ->
-                    if (DarkIconDispatcher.isInAreas(areas, viewBounds)) {
-                        IconColorsImpl(tint, areas)
-                    } else {
-                        null
-                    }
-                }
-            }
+            .map { (areas: Collection<Rect>, tint: Int) -> IconColorsImpl(tint, areas) }
             .flowOn(bgContext)
             .conflate()
             .distinctUntilChanged()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java
index 9a7610d..32ec023 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java
@@ -28,7 +28,6 @@
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.coordinator.HeadsUpCoordinator;
-import com.android.systemui.statusbar.notification.row.NotifBindPipeline.BindCallback;
 import com.android.systemui.statusbar.notification.row.RowContentBindParams;
 import com.android.systemui.statusbar.notification.row.RowContentBindStage;
 
@@ -73,7 +72,10 @@
      * Bind heads up view to the notification row.
      * @param callback callback after heads up view is bound
      */
-    public void bindHeadsUpView(NotificationEntry entry, @Nullable BindCallback callback) {
+    public void bindHeadsUpView(
+            NotificationEntry entry,
+            boolean isPinnedByUser,
+            @Nullable HeadsUpBindCallback callback) {
         RowContentBindParams params = mStage.getStageParams(entry);
         final boolean isImportantMessage = mNotificationMessagingUtil.isImportantMessaging(
                 entry.getSbn(), entry.getImportance());
@@ -84,16 +86,16 @@
         CancellationSignal signal = mStage.requestRebind(entry, en -> {
             mLogger.entryBoundSuccessfully(entry);
             en.getRow().setUsesIncreasedHeadsUpHeight(params.useIncreasedHeadsUpHeight());
-            // requestRebing promises that if we called cancel before this callback would be
+            // requestRebind promises that if we called cancel before this callback would be
             // invoked, then we will not enter this callback, and because we always cancel before
             // adding to this map, we know this will remove the correct signal.
             mOngoingBindCallbacks.remove(entry);
             if (callback != null) {
-                callback.onBindFinished(en);
+                callback.onHeadsUpBindFinished(en, isPinnedByUser);
             }
         });
         abortBindCallback(entry);
-        mLogger.startBindingHun(entry);
+        mLogger.startBindingHun(entry, isPinnedByUser);
         mOngoingBindCallbacks.put(entry, signal);
     }
 
@@ -129,4 +131,14 @@
         mLogger.entryContentViewMarkedFreeable(entry);
         mStage.requestRebind(entry, e -> mLogger.entryUnbound(e));
     }
+
+    /**
+     * Interface for bind callback.
+     */
+    public interface HeadsUpBindCallback {
+        /**
+         * Called when all views are fully bound on the notification.
+         */
+        void onHeadsUpBindFinished(NotificationEntry entry, boolean isPinnedByUser);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderLogger.kt
index c6d2861..e690fa5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderLogger.kt
@@ -1,59 +1,63 @@
 package com.android.systemui.statusbar.notification.interruption
 
-import com.android.systemui.log.dagger.NotificationHeadsUpLog
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.LogLevel.INFO
+import com.android.systemui.log.dagger.NotificationHeadsUpLog
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.logKey
 import javax.inject.Inject
 
 class HeadsUpViewBinderLogger @Inject constructor(@NotificationHeadsUpLog val buffer: LogBuffer) {
-    fun startBindingHun(entry: NotificationEntry) {
-        buffer.log(TAG, INFO, {
-            str1 = entry.logKey
-        }, {
-            "start binding heads up entry $str1 "
-        })
+    fun startBindingHun(entry: NotificationEntry, isPinnedByUser: Boolean) {
+        buffer.log(
+            TAG,
+            INFO,
+            {
+                str1 = entry.logKey
+                bool1 = isPinnedByUser
+            },
+            { "start binding heads up entry $str1. isPinnedByUser=$bool1 " },
+        )
     }
 
     fun currentOngoingBindingAborted(entry: NotificationEntry) {
-        buffer.log(TAG, INFO, {
-            str1 = entry.logKey
-        }, {
-            "aborted potential ongoing heads up entry binding $str1 "
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            { str1 = entry.logKey },
+            { "aborted potential ongoing heads up entry binding $str1 " },
+        )
     }
 
     fun entryBoundSuccessfully(entry: NotificationEntry) {
-        buffer.log(TAG, INFO, {
-            str1 = entry.logKey
-        }, {
-            "heads up entry bound successfully $str1 "
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            { str1 = entry.logKey },
+            { "heads up entry bound successfully $str1 " },
+        )
     }
 
     fun entryUnbound(entry: NotificationEntry) {
-        buffer.log(TAG, INFO, {
-            str1 = entry.logKey
-        }, {
-            "heads up entry unbound successfully $str1 "
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            { str1 = entry.logKey },
+            { "heads up entry unbound successfully $str1 " },
+        )
     }
 
     fun entryContentViewMarkedFreeable(entry: NotificationEntry) {
-        buffer.log(TAG, INFO, {
-            str1 = entry.logKey
-        }, {
-            "start unbinding heads up entry $str1 "
-        })
+        buffer.log(TAG, INFO, { str1 = entry.logKey }, { "start unbinding heads up entry $str1 " })
     }
 
     fun entryBindStageParamsNullOnUnbind(entry: NotificationEntry) {
-        buffer.log(TAG, INFO, {
-            str1 = entry.logKey
-        }, {
-            "heads up entry bind stage params null on unbind $str1 "
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            { str1 = entry.logKey },
+            { "heads up entry bind stage params null on unbind $str1 " },
+        )
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
index 38eaf27..e122ca8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
@@ -77,6 +77,13 @@
         contentBuilder.text = notification.text()
         contentBuilder.skeletonLargeIcon = null // TODO
 
+        val colorsFromNotif = recoveredBuilder.getColors(/* header= */ false)
+        contentBuilder.colors =
+            PromotedNotificationContentModel.Colors(
+                backgroundColor = colorsFromNotif.backgroundColor,
+                primaryTextColor = colorsFromNotif.primaryTextColor,
+            )
+
         recoveredBuilder.style?.extractContent(contentBuilder)
             ?: run { contentBuilder.style = Style.Ineligible }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
index 41ee3b9..0af4043 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
@@ -18,6 +18,7 @@
 
 import android.annotation.DrawableRes
 import android.graphics.drawable.Icon
+import androidx.annotation.ColorInt
 import com.android.internal.widget.NotificationProgressModel
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
 import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi
@@ -39,6 +40,7 @@
     val title: CharSequence?,
     val text: CharSequence?,
     val skeletonLargeIcon: Icon?, // TODO(b/377568176): Make into an IconModel.
+    val colors: Colors,
     val style: Style,
 
     // for CallStyle:
@@ -61,6 +63,7 @@
         var text: CharSequence? = null
         var skeletonLargeIcon: Icon? = null
         var style: Style = Style.Ineligible
+        var colors: Colors = Colors(backgroundColor = 0, primaryTextColor = 0)
 
         // for CallStyle:
         var personIcon: Icon? = null
@@ -83,6 +86,7 @@
                 title = title,
                 text = text,
                 skeletonLargeIcon = skeletonLargeIcon,
+                colors = colors,
                 style = style,
                 personIcon = personIcon,
                 personName = personName,
@@ -102,6 +106,9 @@
         }
     }
 
+    /** The colors used to display the notification. */
+    data class Colors(@ColorInt val backgroundColor: Int, @ColorInt val primaryTextColor: Int)
+
     /** The promotion-eligible style of a notification, or [Style.Ineligible] if not. */
     enum class Style {
         BigPicture,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 5c51ada..b4092cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -37,7 +37,6 @@
 import com.android.app.animation.Interpolators;
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.jank.InteractionJankMonitor.Configuration;
-import com.android.settingslib.Utils;
 import com.android.systemui.Gefingerpoken;
 import com.android.systemui.res.R;
 import com.android.systemui.shade.TouchLogger;
@@ -123,8 +122,8 @@
     }
 
     private void updateColors() {
-        mNormalColor = Utils.getColorAttrDefaultColor(mContext,
-                com.android.internal.R.attr.materialColorSurfaceContainerHigh);
+        mNormalColor = mContext.getColor(
+                com.android.internal.R.color.materialColorSurfaceContainerHigh);
         mTintedRippleColor = mContext.getColor(
                 R.color.notification_ripple_tinted_color);
         mNormalRippleColor = mContext.getColor(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
index a8d59d8..6bfc9f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
@@ -40,6 +40,7 @@
 import com.android.internal.annotations.VisibleForTesting
 import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
 
 private const val TAG = "ChannelDialogController"
@@ -58,11 +59,10 @@
  */
 @SysUISingleton
 class ChannelEditorDialogController @Inject constructor(
-    c: Context,
+    @ShadeDisplayAware private val context: Context,
     private val noMan: INotificationManager,
     private val dialogBuilder: ChannelEditorDialog.Builder
 ) {
-    val context: Context = c.applicationContext
 
     private var prepared = false
     private lateinit var dialog: ChannelEditorDialog
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index c8811fd..5a52c37 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -1247,6 +1247,11 @@
     }
 
     @Override
+    public PinnedStatus getPinnedStatus() {
+        return mPinnedStatus;
+    }
+
+    @Override
     public int getPinnedHeadsUpHeight() {
         return getPinnedHeadsUpHeight(true /* atLeastMinHeight */);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index ef6cad1..f83a1d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -40,6 +40,7 @@
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.notification.Roundable;
 import com.android.systemui.statusbar.notification.RoundableState;
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus;
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.util.Compile;
@@ -201,6 +202,11 @@
         return false;
     }
 
+    @NonNull
+    public PinnedStatus getPinnedStatus() {
+        return PinnedStatus.NotPinned;
+    }
+
     public boolean isHeadsUpAnimatingAway() {
         return false;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java
index 61f4e96..5c4c253 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java
@@ -21,7 +21,6 @@
 import android.annotation.Nullable;
 import android.app.Flags;
 import android.content.Context;
-import android.content.res.TypedArray;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.View;
@@ -115,16 +114,9 @@
     }
 
     private void resolveThemeTextColors() {
-        try (TypedArray ta = mContext.getTheme().obtainStyledAttributes(
-                android.R.style.Theme_DeviceDefault_DayNight, new int[]{
-                        com.android.internal.R.attr.materialColorOnSurface,
-                        com.android.internal.R.attr.materialColorOnSurfaceVariant
-                })) {
-            if (ta != null) {
-                mPrimaryTextColor = ta.getColor(0, mPrimaryTextColor);
-                mSecondaryTextColor = ta.getColor(1, mSecondaryTextColor);
-            }
-        }
+        mPrimaryTextColor = mContext.getColor(com.android.internal.R.color.materialColorOnSurface);
+        mSecondaryTextColor = mContext.getColor(
+                com.android.internal.R.color.materialColorOnSurfaceVariant);
     }
 
     public void bind(@Nullable CharSequence title, @Nullable CharSequence text,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index 34ef639..e440d27 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -35,7 +35,6 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.util.ContrastColorUtil;
-import com.android.settingslib.Utils;
 import com.android.systemui.Dumpable;
 import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.shared.NotificationAddXOnHoverToDismiss;
@@ -83,8 +82,8 @@
                 R.color.notification_state_color_light);
         mDarkColoredStatefulColors = getResources().getColorStateList(
                 R.color.notification_state_color_dark);
-        mNormalColor = Utils.getColorAttrDefaultColor(mContext,
-                com.android.internal.R.attr.materialColorSurfaceContainerHigh);
+        mNormalColor = mContext.getColor(
+                com.android.internal.R.color.materialColorSurfaceContainerHigh);
         mFocusOverlayStroke = getResources().getDimension(R.dimen.notification_focus_stroke_width);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index e141b7c..be9f60d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -43,7 +43,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutManager;
-import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.Handler;
@@ -337,10 +336,7 @@
         Drawable person =  mIconFactory.getBaseIconDrawable(mShortcutInfo);
         if (person == null) {
             person = mContext.getDrawable(R.drawable.ic_person).mutate();
-            TypedArray ta = mContext.obtainStyledAttributes(
-                    new int[]{com.android.internal.R.attr.materialColorPrimary});
-            int colorPrimary = ta.getColor(0, 0);
-            ta.recycle();
+            int colorPrimary = mContext.getColor(com.android.internal.R.color.materialColorPrimary);
             person.setTint(colorPrimary);
         }
         ImageView image = findViewById(R.id.conversation_icon);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
index f8aff69..9d13ab5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
@@ -21,7 +21,6 @@
 import android.graphics.drawable.AnimatedImageDrawable
 import android.view.View
 import android.view.ViewGroup
-import android.view.ViewGroup.MarginLayoutParams
 import com.android.internal.widget.CachingIconView
 import com.android.internal.widget.ConversationLayout
 import com.android.internal.widget.MessagingGroup
@@ -94,13 +93,6 @@
         // Reinspect the notification. Before the super call, because the super call also updates
         // the transformation types and we need to have our values set by then.
         resolveViews()
-        if (Flags.notificationsRedesignAppIcons() && row.isShowingAppIcon) {
-            // Override the margins to be 2dp instead of 4dp according to the new design if we're
-            // showing the app icon.
-            val lp = badgeIconView.layoutParams as MarginLayoutParams
-            lp.setMargins(2, 2, 2, 2)
-            badgeIconView.layoutParams = lp
-        }
         super.onContentUpdated(row)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
index 182fba3..752a8ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
@@ -38,7 +38,6 @@
 import com.android.internal.graphics.ColorUtils;
 import com.android.internal.util.ContrastColorUtil;
 import com.android.internal.widget.CachingIconView;
-import com.android.settingslib.Utils;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.notification.FeedbackIcon;
@@ -344,9 +343,8 @@
         if (customBackgroundColor != 0) {
             return customBackgroundColor;
         }
-        return Utils.getColorAttr(mView.getContext(),
-                        com.android.internal.R.attr.materialColorSurfaceContainerHigh)
-                .getDefaultColor();
+        return mView.getContext().getColor(
+                com.android.internal.R.color.materialColorSurfaceContainerHigh);
     }
 
     public void setLegacy(boolean legacy) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 99edf65..00cd8ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Path;
 import android.graphics.Path.Direction;
@@ -1519,10 +1518,9 @@
         int color = mContainingNotification.getNotificationColor();
         Resources.Theme theme = new ContextThemeWrapper(mContext,
                 com.android.internal.R.style.Theme_DeviceDefault_DayNight).getTheme();
-        try (TypedArray ta = theme.obtainStyledAttributes(
-                new int[]{com.android.internal.R.attr.materialColorPrimary})) {
-            color = ta.getColor(0, color);
-        }
+
+        color = mContext.getColor(com.android.internal.R.color.materialColorPrimary);
+
         mHybridGroupManager.setOverflowNumberColor(mOverflowNumber, color);
     }
 
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 b9e38ab..0720899 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
@@ -83,7 +83,6 @@
 import com.android.internal.policy.SystemBarUtils;
 import com.android.keyguard.BouncerPanelExpansionCalculator;
 import com.android.keyguard.KeyguardSliceView;
-import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
 import com.android.systemui.ExpandHelper;
@@ -2630,6 +2629,7 @@
     private void updateContentHeight() {
         if (SceneContainerFlag.isEnabled()) {
             updateIntrinsicStackHeight();
+            updateStackEndHeightAndStackHeight(mAmbientState.getExpansionFraction());
             return;
         }
 
@@ -4729,10 +4729,10 @@
      * Update colors of section headers, shade footer, and empty shade views.
      */
     void updateDecorViews() {
-        final @ColorInt int onSurface = Utils.getColorAttrDefaultColor(
-                mContext, com.android.internal.R.attr.materialColorOnSurface);
-        final @ColorInt int onSurfaceVariant = Utils.getColorAttrDefaultColor(
-                mContext, com.android.internal.R.attr.materialColorOnSurfaceVariant);
+        final @ColorInt int onSurface = mContext.getColor(
+                com.android.internal.R.color.materialColorOnSurface);
+        final @ColorInt int onSurfaceVariant = mContext.getColor(
+                com.android.internal.R.color.materialColorOnSurfaceVariant);
 
         ColorUpdateLogger colorUpdateLogger = ColorUpdateLogger.getInstance();
         if (colorUpdateLogger != null) {
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 ba707a5..245b1d2 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
@@ -429,9 +429,10 @@
     };
 
     /**
-     * Recalculate sensitiveness without animation; called when waking up while keyguard occluded.
+     * Recalculate sensitiveness without animation; called when waking up while keyguard occluded,
+     * or whenever we update the Lockscreen public mode.
      */
-    public void updateSensitivenessForOccludedWakeup() {
+    public void updateSensitivenessWithoutAnimation() {
         updateSensitivenessWithAnimation(false);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
index bffcae9..b456168 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
@@ -147,8 +147,7 @@
             // The footer needs to be re-inflated every time the theme or the font size changes.
             configuration
                 .inflateLayout<FooterView>(
-                    if (NotifRedesignFooter.isEnabled)
-                        R.layout.status_bar_notification_footer_redesign
+                    if (NotifRedesignFooter.isEnabled) R.layout.notification_2025_footer
                     else R.layout.status_bar_notification_footer,
                     parentView,
                     attachToRoot = false,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
index d1338ea..f2ef2f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
@@ -313,6 +313,7 @@
                     // if it is volume panel.
                     options.setDisallowEnterPictureInPictureWhileLaunching(true)
                 }
+                intent.collectExtraIntentKeys()
                 try {
                     result[0] =
                         ActivityTaskManager.getService()
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 c6af328..7bea480 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -2234,6 +2234,9 @@
 
             // If the state didn't change, we may still need to update public mode
             mLockscreenUserManager.updatePublicMode();
+            if (SceneContainerFlag.isEnabled()) {
+                mStackScrollerController.updateSensitivenessWithoutAnimation();
+            }
         }
         if (mStatusBarStateController.leaveOpenOnKeyguardHide()) {
             if (!mStatusBarStateController.isKeyguardRequested()) {
@@ -2681,7 +2684,7 @@
                 // So if AOD is off or unsupported we need to trigger these updates at screen on
                 // when the keyguard is occluded.
                 mLockscreenUserManager.updatePublicMode();
-                mStackScrollerController.updateSensitivenessForOccludedWakeup();
+                mStackScrollerController.updateSensitivenessWithoutAnimation();
             }
             if (mLaunchCameraWhenFinishedWaking) {
                 startLaunchTransitionTimeout();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerStartable.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerStartable.kt
index 8f4279e..a324e6d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerStartable.kt
@@ -17,8 +17,8 @@
 package com.android.systemui.statusbar.phone
 
 import com.android.systemui.CoreStartable
-import com.android.systemui.common.ui.GlobalConfig
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener
 import javax.inject.Inject
@@ -27,8 +27,8 @@
 class ConfigurationControllerStartable
 @Inject
 constructor(
-    @GlobalConfig private val configurationController: ConfigurationController,
-    private val listeners: Set<@JvmSuppressWildcards ConfigurationListener>
+    @Main private val configurationController: ConfigurationController,
+    private val listeners: Set<@JvmSuppressWildcards ConfigurationListener>,
 ) : CoreStartable {
     override fun start() {
         listeners.forEach { configurationController.addCallback(it) }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index 6cad68f..53a2950 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -23,6 +23,7 @@
 import android.view.View;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.widget.ViewClippingUtil;
@@ -36,6 +37,7 @@
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.HeadsUpStatusBarView;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips;
 import com.android.systemui.statusbar.core.StatusBarRootModernization;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.SourceType;
@@ -153,7 +155,7 @@
             @Override
             public void onLayoutChange(View v, int left, int top, int right, int bottom,
                     int oldLeft, int oldTop, int oldRight, int oldBottom) {
-                if (shouldBeVisible()) {
+                if (shouldHeadsUpStatusBarBeVisible()) {
                     updateTopEntry();
 
                     // trigger scroller to notify the latest panel translation
@@ -217,35 +219,54 @@
 
     private void updateTopEntry() {
         NotificationEntry newEntry = null;
-        if (shouldBeVisible()) {
+        if (shouldHeadsUpStatusBarBeVisible()) {
             newEntry = mHeadsUpManager.getTopEntry();
         }
         NotificationEntry previousEntry = mView.getShowingEntry();
         mView.setEntry(newEntry);
         if (newEntry != previousEntry) {
             if (newEntry == null) {
-                // no heads up anymore, lets start the disappear animation
+                // No longer heads up
                 setPinnedStatus(PinnedStatus.NotPinned);
             } else if (previousEntry == null) {
-                // We now have a headsUp and didn't have one before. Let's start the disappear
-                // animation
-                setPinnedStatus(PinnedStatus.PinnedBySystem);
+                // We now have a heads up when we didn't have one before
+                setPinnedStatus(newEntry.getPinnedStatus());
             }
 
-            String isolatedIconKey;
-            if (newEntry != null) {
-                isolatedIconKey = newEntry.getRepresentativeEntry().getKey();
+            mHeadsUpNotificationIconInteractor.setIsolatedIconNotificationKey(
+                    getIsolatedIconKey(newEntry));
+        }
+    }
+
+    private static @Nullable String getIsolatedIconKey(NotificationEntry newEntry) {
+        if (newEntry == null) {
+            return null;
+        }
+        if (StatusBarNotifChips.isEnabled()) {
+            // If the flag is on, only show the isolated icon if the HUN is pinned by the
+            // *system*. (If the HUN was pinned by the user, then the user tapped the
+            // notification status bar chip and we want to keep the chip showing.)
+            if (newEntry.getPinnedStatus() == PinnedStatus.PinnedBySystem) {
+                return newEntry.getRepresentativeEntry().getKey();
             } else {
-                isolatedIconKey = null;
+                return null;
             }
-            mHeadsUpNotificationIconInteractor.setIsolatedIconNotificationKey(isolatedIconKey);
+        } else {
+            // If the flag is off, we know all HUNs are pinned by the system and should show
+            // the isolated icon
+            return newEntry.getRepresentativeEntry().getKey();
         }
     }
 
     private void setPinnedStatus(PinnedStatus pinnedStatus) {
         if (mPinnedStatus != pinnedStatus) {
             mPinnedStatus = pinnedStatus;
-            if (pinnedStatus.isPinned()) {
+
+            boolean shouldShowHunStatusBar = StatusBarNotifChips.isEnabled()
+                    ? mPinnedStatus == PinnedStatus.PinnedBySystem
+                    // If the flag isn't enabled, all HUNs get the normal treatment.
+                    : mPinnedStatus.isPinned();
+            if (shouldShowHunStatusBar) {
                 updateParentClipping(false /* shouldClip */);
                 mView.setVisibility(View.VISIBLE);
                 show(mView);
@@ -333,23 +354,36 @@
         return mPinnedStatus;
     }
 
-    /**
-     * Should the headsup status bar view be visible right now? This may be different from isShown,
-     * since the headsUp manager might not have notified us yet of the state change.
-     *
-     * @return if the heads up status bar view should be shown
-     * @deprecated use HeadsUpNotificationInteractor.showHeadsUpStatusBar instead.
-     */
-    public boolean shouldBeVisible() {
+    /** True if the device's current state allows us to show HUNs and false otherwise. */
+    private boolean canShowHeadsUp() {
         boolean notificationsShown = !mWakeUpCoordinator.getNotificationsFullyHidden();
-        boolean canShow = !isExpanded() && notificationsShown;
         if (mBypassController.getBypassEnabled() &&
                 (mStatusBarStateController.getState() == StatusBarState.KEYGUARD
                         || mKeyguardStateController.isKeyguardGoingAway())
                 && notificationsShown) {
-            canShow = true;
+            return true;
         }
-        return canShow && mHeadsUpManager.hasPinnedHeadsUp();
+        return !isExpanded() && notificationsShown;
+    }
+
+    /**
+     * True if the headsup status bar view (which has just the HUN icon and app name) should be
+     * visible right now and false otherwise.
+     *
+     * @deprecated use {@link com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor#getStatusBarHeadsUpState()}
+     *    instead.
+     */
+    @Deprecated
+    public boolean shouldHeadsUpStatusBarBeVisible() {
+        if (StatusBarNotifChips.isEnabled()) {
+            return canShowHeadsUp()
+                    && mHeadsUpManager.pinnedHeadsUpStatus() == PinnedStatus.PinnedBySystem;
+            // Note: This means that if mHeadsUpManager.pinnedHeadsUpStatus() == PinnedByUser,
+            // #updateTopEntry won't do anything, so mPinnedStatus will remain as NotPinned and will
+            // *not* update to PinnedByUser.
+        } else {
+            return canShowHeadsUp() && mHeadsUpManager.hasPinnedHeadsUp();
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
index 1cca3ae..d7cc65d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
@@ -180,6 +180,7 @@
                     // if it is volume panel.
                     options.setDisallowEnterPictureInPictureWhileLaunching(true)
                 }
+                intent.collectExtraIntentKeys()
                 try {
                     result[0] =
                         ActivityTaskManager.getService()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
index f19d707..2467e08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
@@ -39,10 +39,12 @@
 import com.android.systemui.shade.ShadeLogger
 import com.android.systemui.shade.ShadeViewController
 import com.android.systemui.shade.StatusBarLongPressGestureDetector
+import com.android.systemui.shade.data.repository.ShadeDisplaysRepository
 import com.android.systemui.shade.display.StatusBarTouchShadeDisplayPolicy
 import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
 import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
 import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
 import com.android.systemui.statusbar.data.repository.StatusBarContentInsetsProviderStore
 import com.android.systemui.statusbar.policy.Clock
 import com.android.systemui.statusbar.policy.ConfigurationController
@@ -83,6 +85,7 @@
     private val darkIconDispatcher: DarkIconDispatcher,
     private val statusBarContentInsetsProvider: StatusBarContentInsetsProvider,
     private val lazyStatusBarShadeDisplayPolicy: Lazy<StatusBarTouchShadeDisplayPolicy>,
+    private val shadeDisplaysRepository: ShadeDisplaysRepository,
 ) : ViewController<PhoneStatusBarView>(view) {
 
     private lateinit var battery: BatteryMeterView
@@ -296,7 +299,19 @@
                     return true
                 }
             }
-            return shadeViewController.handleExternalTouch(event)
+
+            // With the StatusBarConnectedDisplays changes, status bar touches should result in
+            // shade interaction only if ShadeWindowGoesAround.isEnabled or if touch is on the
+            // display which currently hosts the shade.
+            return if (
+                !StatusBarConnectedDisplays.isEnabled ||
+                    ShadeWindowGoesAround.isEnabled ||
+                    context.displayId == shadeDisplaysRepository.displayId.value
+            ) {
+                shadeViewController.handleExternalTouch(event)
+            } else {
+                false
+            }
         }
     }
 
@@ -352,6 +367,7 @@
         @DisplaySpecific private val darkIconDispatcher: DarkIconDispatcher,
         private val statusBarContentInsetsProviderStore: StatusBarContentInsetsProviderStore,
         private val lazyStatusBarShadeDisplayPolicy: Lazy<StatusBarTouchShadeDisplayPolicy>,
+        private val shadeDisplaysRepository: ShadeDisplaysRepository,
     ) {
         fun create(view: PhoneStatusBarView): PhoneStatusBarViewController {
             val statusBarMoveFromCenterAnimationController =
@@ -380,6 +396,7 @@
                 darkIconDispatcher,
                 statusBarContentInsetsProviderStore.defaultDisplay,
                 lazyStatusBarShadeDisplayPolicy,
+                shadeDisplaysRepository,
             )
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index e7c6fb4..324db79 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -51,7 +51,6 @@
 import com.android.keyguard.BouncerPanelExpansionCalculator;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.settingslib.Utils;
 import com.android.systemui.Dumpable;
 import com.android.systemui.animation.ShadeInterpolation;
 import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants;
@@ -82,9 +81,6 @@
 import com.android.systemui.util.wakelock.DelayedWakeLock;
 import com.android.systemui.util.wakelock.WakeLock;
 
-import kotlinx.coroutines.CoroutineDispatcher;
-import kotlinx.coroutines.ExperimentalCoroutinesApi;
-
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -93,6 +89,9 @@
 
 import javax.inject.Inject;
 
+import kotlinx.coroutines.CoroutineDispatcher;
+import kotlinx.coroutines.ExperimentalCoroutinesApi;
+
 /**
  * Controls both the scrim behind the notifications and in front of the notifications (when a
  * security method gets shown).
@@ -1532,17 +1531,17 @@
 
     private void updateThemeColors() {
         if (mScrimBehind == null) return;
-        int background = Utils.getColorAttr(mScrimBehind.getContext(),
-                com.android.internal.R.attr.materialColorSurfaceDim).getDefaultColor();
-        int accent = Utils.getColorAttr(mScrimBehind.getContext(),
-                com.android.internal.R.attr.materialColorPrimary).getDefaultColor();
+        int background = mScrimBehind.getContext().getColor(
+                com.android.internal.R.color.materialColorSurfaceDim);
+        int accent = mScrimBehind.getContext().getColor(
+                com.android.internal.R.color.materialColorPrimary);
         mColors.setMainColor(background);
         mColors.setSecondaryColor(accent);
         final boolean isBackgroundLight = !ContrastColorUtil.isColorDark(background);
         mColors.setSupportsDarkText(isBackgroundLight);
 
-        int surface = Utils.getColorAttr(mScrimBehind.getContext(),
-                com.android.internal.R.attr.materialColorSurface).getDefaultColor();
+        int surface = mScrimBehind.getContext().getColor(
+                com.android.internal.R.color.materialColorSurface);
         for (ScrimState state : ScrimState.values()) {
             state.setSurfaceColor(surface);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index b3cc047..12684fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -37,10 +37,12 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.InitController;
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.power.domain.interactor.PowerInteractor;
 import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.shade.QuickSettingsController;
 import com.android.systemui.shade.ShadeViewController;
@@ -59,6 +61,7 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
 import com.android.systemui.statusbar.notification.domain.interactor.NotificationAlertsInteractor;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor;
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionCondition;
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider;
@@ -69,7 +72,6 @@
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import java.util.Set;
@@ -102,6 +104,7 @@
     private final IStatusBarService mBarService;
     private final DynamicPrivacyController mDynamicPrivacyController;
     private final NotificationListContainer mNotifListContainer;
+    private final DeviceUnlockedInteractor mDeviceUnlockedInteractor;
     private final QuickSettingsController mQsController;
 
     protected boolean mVrMode;
@@ -133,7 +136,8 @@
             VisualInterruptionDecisionProvider visualInterruptionDecisionProvider,
             NotificationRemoteInputManager remoteInputManager,
             NotificationRemoteInputManager.Callback remoteInputManagerCallback,
-            NotificationListContainer notificationListContainer) {
+            NotificationListContainer notificationListContainer,
+            DeviceUnlockedInteractor deviceUnlockedInteractor) {
         mActivityStarter = activityStarter;
         mKeyguardStateController = keyguardStateController;
         mNotificationPanel = panel;
@@ -160,6 +164,7 @@
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
         mNotifListContainer = notificationListContainer;
+        mDeviceUnlockedInteractor = deviceUnlockedInteractor;
 
         IVrManager vrManager = IVrManager.Stub.asInterface(ServiceManager.getService(
                 Context.VR_SERVICE));
@@ -248,14 +253,25 @@
             if (mStatusBarStateController.getState() == StatusBarState.KEYGUARD) {
                 mShadeTransitionController.goToLockedShade(clickedEntry.getRow());
             } else if (clickedEntry.isSensitive().getValue()
-                    && mDynamicPrivacyController.isInLockedDownShade()) {
+                    && isInLockedDownShade()) {
                 mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
+                // launch the bouncer
                 mActivityStarter.dismissKeyguardThenExecute(() -> false /* dismissAction */
                         , null /* cancelRunnable */, false /* afterKeyguardGone */);
             }
         }
     }
 
+    /** @return true if the Shade is shown over the Lockscreen, and the device is locked */
+    private boolean isInLockedDownShade() {
+        if (SceneContainerFlag.isEnabled()) {
+            return mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED
+                    && !mDeviceUnlockedInteractor.getDeviceUnlockStatus().getValue().isUnlocked();
+        } else {
+            return mDynamicPrivacyController.isInLockedDownShade();
+        }
+    }
+
     @Override
     public boolean isDeviceInVrMode() {
         return mVrMode;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java
index b9cba99..d0d0b5c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java
@@ -29,7 +29,6 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.android.settingslib.Utils;
 import com.android.systemui.res.R;
 import com.android.wm.shell.shared.animation.Interpolators;
 
@@ -51,8 +50,8 @@
     }
 
     void updateColor() {
-        final @ColorInt int onSurface = Utils.getColorAttrDefaultColor(mContext,
-                com.android.internal.R.attr.materialColorOnSurface);
+        final @ColorInt int onSurface = mContext.getColor(
+                com.android.internal.R.color.materialColorOnSurface);
         setTextColor(onSurface);
         setBackground(getResources().getDrawable(R.drawable.rounded_bg_full, mContext.getTheme()));
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index 724ba8c..d257288 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -627,8 +627,9 @@
         StatusBarRootModernization.assertInLegacyMode();
 
         // TODO(b/328393714) use HeadsUpNotificationInteractor.showHeadsUpStatusBar instead.
-        boolean headsUpVisible =
-                mHomeStatusBarComponent.getHeadsUpAppearanceController().shouldBeVisible();
+        boolean headsUpVisible = mHomeStatusBarComponent
+                .getHeadsUpAppearanceController()
+                .shouldHeadsUpStatusBarBeVisible();
 
         if (SceneContainerFlag.isEnabled()) {
             // With the scene container, only use the value calculated by the view model to
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt
index 4b71c02..b7ccfa0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt
@@ -21,17 +21,22 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.Logger
+import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
 import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
+import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallLog
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
+import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.stateIn
 
 /**
@@ -47,7 +52,9 @@
 @SysUISingleton
 class OngoingCallInteractor @Inject constructor(
     @Application private val scope: CoroutineScope,
-    activityManagerRepository: ActivityManagerRepository,
+    private val activityManagerRepository: ActivityManagerRepository,
+    private val statusBarModeRepositoryStore: StatusBarModeRepositoryStore,
+    private val statusBarWindowControllerStore: StatusBarWindowControllerStore,
     activeNotificationsInteractor: ActiveNotificationsInteractor,
     @OngoingCallLog private val logBuffer: LogBuffer,
 ) {
@@ -58,46 +65,78 @@
      */
     val ongoingCallState: StateFlow<OngoingCallModel> =
         activeNotificationsInteractor.ongoingCallNotification
-            .flatMapLatest { notificationModel ->
-                when (notificationModel) {
-                    null -> {
-                        logger.d("No active call notification - hiding chip")
-                        flowOf(OngoingCallModel.NoCall)
-                    }
-
-                    else -> combine(
-                        flowOf(notificationModel),
-                        activityManagerRepository.createIsAppVisibleFlow(
-                            creationUid = notificationModel.uid,
-                            logger = logger,
-                            identifyingLogTag = TAG,
-                        ),
-                    ) { model, isVisible ->
-                        when {
-                            isVisible -> {
-                                logger.d({ "Call app is visible: uid=$int1" }) {
-                                    int1 = model.uid
-                                }
-                                OngoingCallModel.InCallWithVisibleApp
-                            }
-
-                            else -> {
-                                logger.d({ "Active call detected: startTime=$long1 hasIcon=$bool1" }) {
-                                    long1 = model.whenTime
-                                    bool1 = model.statusBarChipIconView != null
-                                }
-                                OngoingCallModel.InCall(
-                                    startTimeMs = model.whenTime,
-                                    notificationIconView = model.statusBarChipIconView,
-                                    intent = model.contentIntent,
-                                    notificationKey = model.key,
-                                )
-                            }
-                        }
-                    }
-                }
+            .flatMapLatest { notification ->
+                createOngoingCallStateFlow(
+                    notification = notification
+                )
             }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingCallModel.NoCall)
+            .onEach { state ->
+                setStatusBarRequiredForOngoingCall(state)
+            }
+            .stateIn(
+                scope = scope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = OngoingCallModel.NoCall
+            )
+
+    private fun createOngoingCallStateFlow(
+        notification: ActiveNotificationModel?
+    ): Flow<OngoingCallModel> {
+        if (notification == null) {
+            logger.d("No active call notification - hiding chip")
+            return flowOf(OngoingCallModel.NoCall)
+        }
+
+        return combine(
+            flowOf(notification),
+            activityManagerRepository.createIsAppVisibleFlow(
+                creationUid = notification.uid,
+                logger = logger,
+                identifyingLogTag = TAG,
+            )
+        ) { model, isVisible ->
+            deriveOngoingCallState(model, isVisible)
+        }
+    }
+
+    private fun deriveOngoingCallState(
+        model: ActiveNotificationModel,
+        isVisible: Boolean
+    ): OngoingCallModel {
+        return when {
+            isVisible -> {
+                logger.d({ "Call app is visible: uid=$int1" }) {
+                    int1 = model.uid
+                }
+                OngoingCallModel.InCallWithVisibleApp
+            }
+
+            else -> {
+                logger.d({ "Active call detected: startTime=$long1 hasIcon=$bool1" }) {
+                    long1 = model.whenTime
+                    bool1 = model.statusBarChipIconView != null
+                }
+                OngoingCallModel.InCall(
+                    startTimeMs = model.whenTime,
+                    notificationIconView = model.statusBarChipIconView,
+                    intent = model.contentIntent,
+                    notificationKey = model.key
+                )
+            }
+        }
+    }
+
+    private fun setStatusBarRequiredForOngoingCall(state: OngoingCallModel) {
+        val statusBarRequired = state is OngoingCallModel.InCall
+        // TODO(b/382808183): Create a single repository that can be utilized in
+        //  `statusBarModeRepositoryStore` and `statusBarWindowControllerStore` so we do not need
+        //  two separate calls to force the status bar to stay visible.
+        statusBarModeRepositoryStore.defaultDisplay.setOngoingProcessRequiresStatusBarVisible(
+            statusBarRequired
+        )
+        statusBarWindowControllerStore.defaultDisplay
+            .setOngoingProcessRequiresStatusBarVisible(statusBarRequired)
+    }
 
     companion object {
         private val TAG = "OngoingCall"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileContentDescriptionViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileContentDescriptionViewBinder.kt
new file mode 100644
index 0000000..c720b1d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileContentDescriptionViewBinder.kt
@@ -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.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.ui.binder
+
+import android.view.View
+import com.android.systemui.statusbar.pipeline.mobile.ui.model.MobileContentDescription
+
+object MobileContentDescriptionViewBinder {
+    fun bind(contentDescription: MobileContentDescription?, view: View) {
+        view.contentDescription =
+            when (contentDescription) {
+                null -> null
+                else -> contentDescription.loadContentDescription(view.context)
+            }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
index 31d349e..788f041 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
@@ -29,9 +29,9 @@
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.settingslib.graph.SignalDrawable
 import com.android.systemui.Flags.statusBarStaticInoutIndicators
-import com.android.systemui.common.ui.binder.ContentDescriptionViewBinder
 import com.android.systemui.common.ui.binder.IconViewBinder
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.DarkIconDispatcher
@@ -48,12 +48,8 @@
 import kotlinx.coroutines.awaitCancellation
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.distinctUntilChanged
-import com.android.app.tracing.coroutines.launchTraced as launch
 
-private data class Colors(
-    @ColorInt val tint: Int,
-    @ColorInt val contrast: Int,
-)
+private data class Colors(@ColorInt val tint: Int, @ColorInt val contrast: Int)
 
 object MobileIconBinder {
     /** Binds the view to the view-model, continuing to update the former based on the latter */
@@ -87,7 +83,7 @@
             MutableStateFlow(
                 Colors(
                     tint = DarkIconDispatcher.DEFAULT_ICON_TINT,
-                    contrast = DarkIconDispatcher.DEFAULT_INVERSE_ICON_TINT
+                    contrast = DarkIconDispatcher.DEFAULT_INVERSE_ICON_TINT,
                 )
             )
         val decorTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor)
@@ -105,7 +101,7 @@
                             viewModel.verboseLogger?.logBinderReceivedVisibility(
                                 view,
                                 viewModel.subscriptionId,
-                                isVisible
+                                isVisible,
                             )
                             view.isVisible = isVisible
                             // [StatusIconContainer] can get out of sync sometimes. Make sure to
@@ -152,7 +148,7 @@
 
                     launch {
                         viewModel.contentDescription.distinctUntilChanged().collect {
-                            ContentDescriptionViewBinder.bind(it, view)
+                            MobileContentDescriptionViewBinder.bind(it, view)
                         }
                     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/MobileContentDescription.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/MobileContentDescription.kt
new file mode 100644
index 0000000..84fa073
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/MobileContentDescription.kt
@@ -0,0 +1,43 @@
+/*
+ * 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.pipeline.mobile.ui.model
+
+import android.annotation.StringRes
+import android.content.Context
+import com.android.systemui.res.R
+
+sealed interface MobileContentDescription {
+    fun loadContentDescription(context: Context): String
+
+    /**
+     * Content description for cellular parameterizes the [networkName] which comes from the system
+     */
+    data class Cellular(val networkName: String, @StringRes val levelDescriptionRes: Int) :
+        MobileContentDescription {
+        override fun loadContentDescription(context: Context): String =
+            context.getString(
+                R.string.accessibility_phone_string_format,
+                networkName,
+                context.getString(levelDescriptionRes),
+            )
+    }
+
+    data class SatelliteContentDescription(@StringRes val resId: Int) : MobileContentDescription {
+        override fun loadContentDescription(context: Context): String =
+            context.getString(this.resId)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
index 103b0e3..0bd3426 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
 
-import com.android.settingslib.AccessibilityContentDescriptions
 import com.android.systemui.Flags.statusBarStaticInoutIndicators
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
@@ -28,6 +27,7 @@
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractor
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
 import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
+import com.android.systemui.statusbar.pipeline.mobile.ui.model.MobileContentDescription
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
 import kotlinx.coroutines.CoroutineScope
@@ -50,7 +50,7 @@
     /** True if this view should be visible at all. */
     val isVisible: StateFlow<Boolean>
     val icon: Flow<SignalIconModel>
-    val contentDescription: Flow<ContentDescription?>
+    val contentDescription: Flow<MobileContentDescription?>
     val roaming: Flow<Boolean>
     /** The RAT icon (LTE, 3G, 5G, etc) to be displayed. Null if we shouldn't show anything */
     val networkTypeIcon: Flow<Icon.Resource?>
@@ -95,10 +95,7 @@
     }
 
     private val satelliteProvider by lazy {
-        CarrierBasedSatelliteViewModelImpl(
-            subscriptionId,
-            iconInteractor,
-        )
+        CarrierBasedSatelliteViewModelImpl(subscriptionId, iconInteractor)
     }
 
     /**
@@ -123,7 +120,7 @@
 
     override val icon: Flow<SignalIconModel> = vmProvider.flatMapLatest { it.icon }
 
-    override val contentDescription: Flow<ContentDescription?> =
+    override val contentDescription: Flow<MobileContentDescription?> =
         vmProvider.flatMapLatest { it.contentDescription }
 
     override val roaming: Flow<Boolean> = vmProvider.flatMapLatest { it.roaming }
@@ -154,8 +151,7 @@
     override val isVisible: StateFlow<Boolean> = MutableStateFlow(true)
     override val icon: Flow<SignalIconModel> = interactor.signalLevelIcon
 
-    override val contentDescription: Flow<ContentDescription> =
-        MutableStateFlow(ContentDescription.Loaded(""))
+    override val contentDescription: Flow<MobileContentDescription?> = MutableStateFlow(null)
 
     /** These fields are not used for satellite icons currently */
     override val roaming: Flow<Boolean> = flowOf(false)
@@ -206,27 +202,42 @@
 
     override val icon: Flow<SignalIconModel> = iconInteractor.signalLevelIcon
 
-    override val contentDescription: Flow<ContentDescription?> =
-        iconInteractor.signalLevelIcon
-            .map {
-                // We expect the signal icon to be cellular here since this is the cellular vm
-                if (it !is SignalIconModel.Cellular) {
-                    null
-                } else {
-                    val resId =
-                        AccessibilityContentDescriptions.getDescriptionForLevel(
-                            it.level,
-                            it.numberOfLevels
+    override val contentDescription: Flow<MobileContentDescription?> =
+        combine(iconInteractor.signalLevelIcon, iconInteractor.networkName) { icon, nameModel ->
+                when (icon) {
+                    is SignalIconModel.Cellular ->
+                        MobileContentDescription.Cellular(
+                            nameModel.name,
+                            icon.levelDescriptionRes(),
                         )
-                    if (resId != 0) {
-                        ContentDescription.Resource(resId)
-                    } else {
-                        null
-                    }
+                    else -> null
                 }
             }
             .stateIn(scope, SharingStarted.WhileSubscribed(), null)
 
+    private fun SignalIconModel.Cellular.levelDescriptionRes() =
+        when (level) {
+            0 -> R.string.accessibility_no_signal
+            1 -> R.string.accessibility_one_bar
+            2 -> R.string.accessibility_two_bars
+            3 -> R.string.accessibility_three_bars
+            4 -> {
+                if (numberOfLevels == 6) {
+                    R.string.accessibility_four_bars
+                } else {
+                    R.string.accessibility_signal_full
+                }
+            }
+            5 -> {
+                if (numberOfLevels == 6) {
+                    R.string.accessibility_signal_full
+                } else {
+                    R.string.accessibility_no_signal
+                }
+            }
+            else -> R.string.accessibility_no_signal
+        }
+
     private val showNetworkTypeIcon: Flow<Boolean> =
         combine(
                 iconInteractor.isDataConnected,
@@ -248,10 +259,9 @@
             .stateIn(scope, SharingStarted.WhileSubscribed(), false)
 
     override val networkTypeIcon: Flow<Icon.Resource?> =
-        combine(
-                iconInteractor.networkTypeIconGroup,
-                showNetworkTypeIcon,
-            ) { networkTypeIconGroup, shouldShow ->
+        combine(iconInteractor.networkTypeIconGroup, showNetworkTypeIcon) {
+                networkTypeIconGroup,
+                shouldShow ->
                 val desc =
                     if (networkTypeIconGroup.contentDescription != 0)
                         ContentDescription.Resource(networkTypeIconGroup.contentDescription)
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 08a98c3..12f578c 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
@@ -161,6 +161,13 @@
             )
             .stateIn(scope, SharingStarted.WhileSubscribed(), true)
 
+    /** True if any known mobile network is currently using a non terrestrial network */
+    val isAnyConnectionNtn =
+        iconsInteractor.icons.aggregateOver(selector = { it.isNonTerrestrial }, false) {
+            nonTerrestrialNetworks ->
+            nonTerrestrialNetworks.any { it == true }
+        }
+
     companion object {
         const val TAG = "DeviceBasedSatelliteInteractor"
 
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 f3d5139..ea915ef 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
@@ -114,34 +114,39 @@
 
     private val showIcon =
         if (interactor.isOpportunisticSatelliteIconEnabled) {
-            canShowIcon
-                .flatMapLatest { canShow ->
-                    if (!canShow) {
-                        flowOf(false)
-                    } else {
-                        combine(
-                            shouldShowIconForOosAfterHysteresis,
-                            interactor.connectionState,
-                            interactor.isWifiActive,
-                            airplaneModeRepository.isAirplaneMode,
-                        ) { showForOos, connectionState, isWifiActive, isAirplaneMode ->
-                            if (isWifiActive || isAirplaneMode) {
-                                false
-                            } else {
-                                showForOos ||
-                                    connectionState == SatelliteConnectionState.On ||
-                                    connectionState == SatelliteConnectionState.Connected
+                canShowIcon
+                    .flatMapLatest { canShow ->
+                        if (!canShow) {
+                            flowOf(false)
+                        } else {
+                            combine(
+                                shouldShowIconForOosAfterHysteresis,
+                                interactor.isAnyConnectionNtn,
+                                interactor.connectionState,
+                                interactor.isWifiActive,
+                                airplaneModeRepository.isAirplaneMode,
+                            ) { showForOos, anyNtn, connectionState, isWifiActive, isAirplaneMode ->
+                                // anyNtn means that there is some mobile network using ntn, and the
+                                // mobile icon will show its own satellite icon
+                                if (isWifiActive || isAirplaneMode || anyNtn) {
+                                    false
+                                } else {
+                                    // Show for out of service (which has a hysteresis), or ignore
+                                    // the hysteresis if we're already connected
+                                    showForOos ||
+                                        connectionState == SatelliteConnectionState.On ||
+                                        connectionState == SatelliteConnectionState.Connected
+                                }
                             }
                         }
                     }
-                }
-                .distinctUntilChanged()
-                .logDiffsForTable(
-                    tableLog,
-                    columnPrefix = "vm",
-                    columnName = COL_VISIBLE,
-                    initialValue = false,
-                )
+                    .distinctUntilChanged()
+                    .logDiffsForTable(
+                        tableLog,
+                        columnPrefix = "vm",
+                        columnName = COL_VISIBLE,
+                        initialValue = false,
+                    )
             } else {
                 flowOf(false)
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
index c52275a9..6e9e1ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
@@ -41,6 +41,7 @@
 import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle
 import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
 import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
+import com.android.systemui.statusbar.notification.headsup.PinnedStatus
 import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
 import com.android.systemui.statusbar.phone.domain.interactor.LightsOutInteractor
 import com.android.systemui.statusbar.pipeline.shared.domain.interactor.CollapsedStatusBarInteractor
@@ -235,14 +236,18 @@
     override val isClockVisible: Flow<VisibilityModel> =
         combine(
             shouldHomeStatusBarBeVisible,
-            headsUpNotificationInteractor.showHeadsUpStatusBar,
+            headsUpNotificationInteractor.statusBarHeadsUpState,
             collapsedStatusBarInteractor.visibilityViaDisableFlags,
-        ) { shouldStatusBarBeVisible, showHeadsUp, visibilityViaDisableFlags ->
+        ) { shouldStatusBarBeVisible, headsUpState, visibilityViaDisableFlags ->
+            val hideClockForHeadsUp = headsUpState == PinnedStatus.PinnedBySystem
             val showClock =
-                shouldStatusBarBeVisible && visibilityViaDisableFlags.isClockAllowed && !showHeadsUp
+                shouldStatusBarBeVisible &&
+                    visibilityViaDisableFlags.isClockAllowed &&
+                    !hideClockForHeadsUp
             // Always use View.INVISIBLE here, so that animations work
             VisibilityModel(showClock.toVisibleOrInvisible(), visibilityViaDisableFlags.animate)
         }
+
     override val isNotificationIconContainerVisible: Flow<VisibilityModel> =
         combine(
             shouldHomeStatusBarBeVisible,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 16d5f8d..2b0bf1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -24,7 +24,6 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.ColorStateList;
-import android.content.res.TypedArray;
 import android.graphics.BlendMode;
 import android.graphics.Color;
 import android.graphics.PorterDuff;
@@ -174,11 +173,8 @@
         mTextWatcher = new SendButtonTextWatcher();
         mEditorActionHandler = new EditorActionHandler();
         mUiEventLogger = Dependency.get(UiEventLogger.class);
-        TypedArray ta = getContext().getTheme().obtainStyledAttributes(new int[]{
-                com.android.internal.R.attr.materialColorSurfaceDim,
-        });
-        mLastBackgroundColor = ta.getColor(0, 0);
-        ta.recycle();
+        mLastBackgroundColor = getContext().getColor(
+                com.android.internal.R.color.materialColorSurfaceDim);
     }
 
     // TODO(b/193539698): move to Controller, since we're just directly accessing a system service
@@ -229,13 +225,10 @@
             textColor = mContext.getColorStateList(R.color.remote_input_text);
             hintColor = mContext.getColor(R.color.remote_input_hint);
             deleteFgColor = textColor.getDefaultColor();
-            try (TypedArray ta = getContext().getTheme().obtainStyledAttributes(new int[]{
-                    com.android.internal.R.attr.materialColorSurfaceDim,
-                    com.android.internal.R.attr.materialColorSurfaceVariant
-            })) {
-                editBgColor = ta.getColor(0, backgroundColor);
-                deleteBgColor = ta.getColor(1, Color.GRAY);
-            }
+            editBgColor = getContext().getColor(
+                    com.android.internal.R.color.materialColorSurfaceDim);
+            deleteBgColor = getContext().getColor(
+                    com.android.internal.R.color.materialColorSurfaceVariant);
         }
 
         mEditText.setTextColor(textColor);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
index 9187e3c..d1e807f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
@@ -23,7 +23,6 @@
 import com.android.internal.R;
 import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
 import com.android.settingslib.notification.modes.ZenIconLoader;
-import com.android.systemui.common.ui.GlobalConfig;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Application;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -111,7 +110,7 @@
      * wrong updates in case of secondary displays.
      */
     @Binds
-    ConfigurationController bindConfigurationController(@GlobalConfig ConfigurationController impl);
+    ConfigurationController bindConfigurationController(@Main ConfigurationController impl);
 
     /** */
     @Binds
@@ -189,14 +188,14 @@
     /** */
     @Binds
     @SysUISingleton
-    @GlobalConfig
+    @Main
     ConfigurationForwarder provideGlobalConfigurationForwarder(
-            @GlobalConfig ConfigurationController configurationController);
+            @Main ConfigurationController configurationController);
 
     /** */
     @Provides
     @SysUISingleton
-    @GlobalConfig
+    @Main
     static ConfigurationController provideGlobalConfigurationController(
             @Application Context context, ConfigurationControllerImpl.Factory factory) {
         return factory.create(context);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt
index fe1d647..6175ea1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt
@@ -35,6 +35,7 @@
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
 
 /**
@@ -59,7 +60,7 @@
 
     private val showingHeadsUpStatusBar: Flow<Boolean> =
         if (SceneContainerFlag.isEnabled) {
-            headsUpNotificationInteractor.showHeadsUpStatusBar
+            headsUpNotificationInteractor.statusBarHeadsUpState.map { it.isPinned }
         } else {
             flowOf(false)
         }
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
index 7475388..0a10b44 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
@@ -18,7 +18,7 @@
 
 import android.os.VibrationEffect
 import android.view.View
-import androidx.annotation.AttrRes
+import androidx.annotation.ColorRes
 import com.android.internal.logging.InstanceId
 import com.android.systemui.common.shared.model.Text
 import com.android.systemui.common.shared.model.TintedIcon
@@ -52,8 +52,8 @@
 ) : TemporaryViewInfo() {
     companion object {
         // LINT.IfChange
-        @AttrRes val DEFAULT_ICON_TINT = com.android.internal.R.attr.materialColorOnSecondaryFixed
-        // LINT.ThenChange(systemui/res/layout/chipbar.xml)
+        @ColorRes val DEFAULT_ICON_TINT = com.android.internal.R.color.materialColorOnSecondaryFixed
+        // LINT.ThenChange(/packages/SystemUI/res/layout/chipbar.xml)
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/util/view/ViewUtil.kt b/packages/SystemUI/src/com/android/systemui/util/view/ViewUtil.kt
index 6160b00..5b48c1f 100644
--- a/packages/SystemUI/src/com/android/systemui/util/view/ViewUtil.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/view/ViewUtil.kt
@@ -35,27 +35,21 @@
     fun touchIsWithinView(view: View, x: Float, y: Float): Boolean {
         val left = view.locationOnScreen[0]
         val top = view.locationOnScreen[1]
-        return left <= x &&
-                x <= left + view.width &&
-                top <= y &&
-                y <= top + view.height
+        return left <= x && x <= left + view.width && top <= y && y <= top + view.height
     }
 
-    /**
-     * Sets [outRect] to be the view's location within its window.
-     */
-    fun setRectToViewWindowLocation(view: View, outRect: Rect) {
-        val locInWindow = IntArray(2)
-        view.getLocationInWindow(locInWindow)
-
-        val x = locInWindow[0]
-        val y = locInWindow[1]
-
-        outRect.set(
-            x,
-            y,
-            x + view.width,
-            y + view.height,
-        )
-    }
+    /** Sets [outRect] to be the view's location within its window. */
+    fun setRectToViewWindowLocation(view: View, outRect: Rect) = view.viewBoundsOnScreen(outRect)
 }
+
+fun View.viewBoundsOnScreen(outRect: Rect) {
+    val locInWindow = IntArray(2)
+    getLocationInWindow(locInWindow)
+
+    val x = locInWindow[0]
+    val y = locInWindow[1]
+
+    outRect.set(x, y, x + width, y + height)
+}
+
+fun View.viewBoundsOnScreen(): Rect = Rect().also { viewBoundsOnScreen(it) }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/domain/VolumeDialogRingerInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/domain/VolumeDialogRingerInteractor.kt
index b83613b..4071918 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/domain/VolumeDialogRingerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/domain/VolumeDialogRingerInteractor.kt
@@ -20,7 +20,6 @@
 import android.media.AudioManager.RINGER_MODE_NORMAL
 import android.media.AudioManager.RINGER_MODE_SILENT
 import android.media.AudioManager.RINGER_MODE_VIBRATE
-import android.provider.Settings
 import com.android.settingslib.volume.data.repository.AudioSystemRepository
 import com.android.settingslib.volume.shared.model.RingerMode
 import com.android.systemui.plugins.VolumeDialogController
@@ -66,11 +65,6 @@
                             }
                         },
                 currentRingerMode = RingerMode(state.ringerModeInternal),
-                isEnabled =
-                    !(state.zenMode == Settings.Global.ZEN_MODE_ALARMS ||
-                        state.zenMode == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS ||
-                        (state.zenMode == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS &&
-                            state.disallowRinger)),
                 isMuted = it.level == 0 || it.muted,
                 level = it.level,
                 levelMax = it.levelMax,
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/shared/model/VolumeDialogRingerModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/shared/model/VolumeDialogRingerModel.kt
index 3c24e02..84a8280 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/shared/model/VolumeDialogRingerModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/shared/model/VolumeDialogRingerModel.kt
@@ -23,8 +23,6 @@
     val availableModes: List<RingerMode>,
     /** Current ringer mode internal */
     val currentRingerMode: RingerMode,
-    /** whether the ringer is allowed given the current ZenMode */
-    val isEnabled: Boolean,
     /** Whether the current ring stream level is zero or the controller state is muted */
     val isMuted: Boolean,
     /** Ring stream level */
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
index 3bd2721..f04fb2c 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
@@ -30,10 +30,10 @@
 import androidx.dynamicanimation.animation.SpringAnimation
 import androidx.dynamicanimation.animation.SpringForce
 import com.android.internal.R as internalR
-import com.android.settingslib.Utils
 import com.android.systemui.res.R
 import com.android.systemui.util.children
 import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
+import com.android.systemui.volume.dialog.ringer.ui.util.VolumeDialogRingerDrawerTransitionListener
 import com.android.systemui.volume.dialog.ringer.ui.viewmodel.RingerButtonUiModel
 import com.android.systemui.volume.dialog.ringer.ui.viewmodel.RingerButtonViewModel
 import com.android.systemui.volume.dialog.ringer.ui.viewmodel.RingerDrawerState
@@ -42,6 +42,7 @@
 import com.android.systemui.volume.dialog.ringer.ui.viewmodel.VolumeDialogRingerDrawerViewModel
 import com.android.systemui.volume.dialog.ui.utils.suspendAnimate
 import javax.inject.Inject
+import kotlin.properties.Delegates
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.flow.launchIn
@@ -71,6 +72,27 @@
         val drawerContainer = view.requireViewById<MotionLayout>(R.id.volume_ringer_drawer)
         val unselectedButtonUiModel = RingerButtonUiModel.getUnselectedButton(view.context)
         val selectedButtonUiModel = RingerButtonUiModel.getSelectedButton(view.context)
+        val volumeDialogBgSmallRadius =
+            view.context.resources.getDimensionPixelSize(
+                R.dimen.volume_dialog_background_square_corner_radius
+            )
+        val volumeDialogBgFullRadius =
+            view.context.resources.getDimensionPixelSize(
+                R.dimen.volume_dialog_background_corner_radius
+            )
+        var backgroundAnimationProgress: Float by
+            Delegates.observable(0F) { _, _, progress ->
+                volumeDialogBackgroundView.applyCorners(
+                    fullRadius = volumeDialogBgFullRadius,
+                    diff = volumeDialogBgFullRadius - volumeDialogBgSmallRadius,
+                    progress,
+                )
+            }
+        val ringerDrawerTransitionListener = VolumeDialogRingerDrawerTransitionListener {
+            backgroundAnimationProgress = it
+        }
+        drawerContainer.setTransitionListener(ringerDrawerTransitionListener)
+        volumeDialogBackgroundView.background = volumeDialogBackgroundView.background.mutate()
         viewModel.ringerViewModel
             .onEach { ringerState ->
                 when (ringerState) {
@@ -87,10 +109,8 @@
                                     selectedButtonUiModel,
                                     unselectedButtonUiModel,
                                 )
+                                ringerDrawerTransitionListener.setProgressChangeEnabled(true)
                                 drawerContainer.closeDrawer(uiModel.currentButtonIndex)
-                                volumeDialogBackgroundView.setBackgroundResource(
-                                    R.drawable.volume_dialog_background
-                                )
                             }
 
                             is RingerDrawerState.Closed -> {
@@ -103,11 +123,31 @@
                                         uiModel,
                                         selectedButtonUiModel,
                                         unselectedButtonUiModel,
+                                        onProgressChanged = { progress, isReverse ->
+                                            // Let's make button progress when switching matches
+                                            // motionLayout transition progress. When full radius,
+                                            // progress is 0.0. When small radius, progress is 1.0.
+                                            backgroundAnimationProgress =
+                                                if (isReverse) {
+                                                    1F - progress
+                                                } else {
+                                                    progress
+                                                }
+                                        },
                                     ) {
+                                        if (
+                                            uiModel.currentButtonIndex ==
+                                                uiModel.availableButtons.size - 1
+                                        ) {
+                                            ringerDrawerTransitionListener.setProgressChangeEnabled(
+                                                false
+                                            )
+                                        } else {
+                                            ringerDrawerTransitionListener.setProgressChangeEnabled(
+                                                true
+                                            )
+                                        }
                                         drawerContainer.closeDrawer(uiModel.currentButtonIndex)
-                                        volumeDialogBackgroundView.setBackgroundResource(
-                                            R.drawable.volume_dialog_background
-                                        )
                                     }
                                 }
                             }
@@ -120,16 +160,18 @@
                                     unselectedButtonUiModel,
                                 )
                                 // Open drawer
+                                if (
+                                    uiModel.currentButtonIndex == uiModel.availableButtons.size - 1
+                                ) {
+                                    ringerDrawerTransitionListener.setProgressChangeEnabled(false)
+                                } else {
+                                    ringerDrawerTransitionListener.setProgressChangeEnabled(true)
+                                }
                                 drawerContainer.transitionToState(
                                     R.id.volume_dialog_ringer_drawer_open
                                 )
-                                if (
-                                    uiModel.currentButtonIndex != uiModel.availableButtons.size - 1
-                                ) {
-                                    volumeDialogBackgroundView.setBackgroundResource(
-                                        R.drawable.volume_dialog_background_small_radius
-                                    )
-                                }
+                                volumeDialogBackgroundView.background =
+                                    volumeDialogBackgroundView.background.mutate()
                             }
                         }
                     }
@@ -150,6 +192,7 @@
         uiModel: RingerViewModel,
         selectedButtonUiModel: RingerButtonUiModel,
         unselectedButtonUiModel: RingerButtonUiModel,
+        onProgressChanged: (Float, Boolean) -> Unit = { _, _ -> },
         onAnimationEnd: Runnable? = null,
     ) {
         ensureChildCount(R.layout.volume_ringer_button, uiModel.availableButtons.size)
@@ -177,10 +220,26 @@
                         CLOSE_DRAWER_DELAY,
                     )
                 }
-
-            // We only need to execute on roundness animation end once.
-            selectedButton.animateTo(selectedButtonUiModel, roundnessAnimationEndListener)
-            unselectedButton.animateTo(unselectedButtonUiModel)
+            // We only need to execute on roundness animation end and volume dialog background
+            // progress update once because these changes should be applied once on volume dialog
+            // background and ringer drawer views.
+            selectedButton.animateTo(
+                selectedButtonUiModel,
+                if (uiModel.currentButtonIndex == count - 1) {
+                    onProgressChanged
+                } else {
+                    { _, _ -> }
+                },
+                roundnessAnimationEndListener,
+            )
+            unselectedButton.animateTo(
+                unselectedButtonUiModel,
+                if (previousIndex == count - 1) {
+                    onProgressChanged
+                } else {
+                    { _, _ -> }
+                },
+            )
         } else {
             bindButtons(viewModel, uiModel, onAnimationEnd)
         }
@@ -234,15 +293,11 @@
                 }
             if (isSelected && !isAnimated) {
                 setBackgroundResource(R.drawable.volume_drawer_selection_bg)
-                setColorFilter(
-                    Utils.getColorAttrDefaultColor(context, internalR.attr.materialColorOnPrimary)
-                )
+                setColorFilter(context.getColor(internalR.color.materialColorOnPrimary))
                 background = background.mutate()
             } else if (!isAnimated) {
                 setBackgroundResource(R.drawable.volume_ringer_item_bg)
-                setColorFilter(
-                    Utils.getColorAttrDefaultColor(context, internalR.attr.materialColorOnSurface)
-                )
+                setColorFilter(context.getColor(internalR.color.materialColorOnSurface))
                 background = background.mutate()
             }
             setOnClickListener {
@@ -366,6 +421,7 @@
 
     private suspend fun ImageButton.animateTo(
         ringerButtonUiModel: RingerButtonUiModel,
+        onProgressChanged: (Float, Boolean) -> Unit = { _, _ -> },
         roundnessAnimationEndListener: DynamicAnimation.OnAnimationEndListener? = null,
     ) {
         val roundnessAnimation =
@@ -376,6 +432,7 @@
             ringerButtonUiModel.cornerRadius - (background as GradientDrawable).cornerRadius
         val roundnessAnimationUpdateListener =
             DynamicAnimation.OnAnimationUpdateListener { _, value, _ ->
+                onProgressChanged(value, cornerRadiusDiff > 0F)
                 (background as GradientDrawable).cornerRadius = radius + value * cornerRadiusDiff
                 background.invalidateSelf()
             }
@@ -406,4 +463,9 @@
             )
         }
     }
+
+    private fun View.applyCorners(fullRadius: Int, diff: Int, progress: Float) {
+        (background as GradientDrawable).cornerRadius = fullRadius - progress * diff
+        background.invalidateSelf()
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/util/VolumeDialogRingerDrawerTransitionListener.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/util/VolumeDialogRingerDrawerTransitionListener.kt
new file mode 100644
index 0000000..6e3db0a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/util/VolumeDialogRingerDrawerTransitionListener.kt
@@ -0,0 +1,51 @@
+/*
+ * 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.volume.dialog.ringer.ui.util
+
+import androidx.constraintlayout.motion.widget.MotionLayout
+
+class VolumeDialogRingerDrawerTransitionListener(private val onProgressChanged: (Float) -> Unit) :
+    MotionLayout.TransitionListener {
+
+    private var notifyProgressChangeEnabled = true
+
+    fun setProgressChangeEnabled(enabled: Boolean) {
+        notifyProgressChangeEnabled = enabled
+    }
+
+    override fun onTransitionStarted(motionLayout: MotionLayout?, startId: Int, endId: Int) {}
+
+    override fun onTransitionChange(
+        motionLayout: MotionLayout?,
+        startId: Int,
+        endId: Int,
+        progress: Float,
+    ) {
+        if (notifyProgressChangeEnabled) {
+            onProgressChanged(progress)
+        }
+    }
+
+    override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) {}
+
+    override fun onTransitionTrigger(
+        motionLayout: MotionLayout?,
+        triggerId: Int,
+        positive: Boolean,
+        progress: Float,
+    ) {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/RingerButtonUiModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/RingerButtonUiModel.kt
index 3c46567..832f1c3 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/RingerButtonUiModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/RingerButtonUiModel.kt
@@ -31,30 +31,20 @@
     companion object {
         fun getUnselectedButton(context: Context): RingerButtonUiModel {
             return RingerButtonUiModel(
-                tintColor =
-                    Utils.getColorAttrDefaultColor(context, internalR.attr.materialColorOnSurface),
-                backgroundColor =
-                    Utils.getColorAttrDefaultColor(
-                        context,
-                        internalR.attr.materialColorSurfaceContainerHighest,
-                    ),
-                cornerRadius =
-                    context.resources.getDimensionPixelSize(
-                        R.dimen.volume_dialog_background_square_corner_radius
-                    ),
+                tintColor = context.getColor(internalR.color.materialColorOnSurface),
+                backgroundColor = context.getColor(
+                    internalR.color.materialColorSurfaceContainerHighest),
+                cornerRadius = context.resources.getDimensionPixelSize(
+                    R.dimen.volume_dialog_background_square_corner_radius),
             )
         }
 
         fun getSelectedButton(context: Context): RingerButtonUiModel {
             return RingerButtonUiModel(
-                tintColor =
-                    Utils.getColorAttrDefaultColor(context, internalR.attr.materialColorOnPrimary),
-                backgroundColor =
-                    Utils.getColorAttrDefaultColor(context, internalR.attr.materialColorPrimary),
-                cornerRadius =
-                    context.resources.getDimensionPixelSize(
-                        R.dimen.volume_dialog_ringer_selected_button_background_radius
-                    ),
+                tintColor = context.getColor(internalR.color.materialColorOnPrimary),
+                backgroundColor = context.getColor(internalR.color.materialColorPrimary),
+                cornerRadius = context.resources.getDimensionPixelSize(
+                    R.dimen.volume_dialog_ringer_selected_button_background_radius),
             )
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt
index e646636..627d75e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt
@@ -21,10 +21,13 @@
 import android.media.AudioManager.RINGER_MODE_NORMAL
 import android.media.AudioManager.RINGER_MODE_SILENT
 import android.media.AudioManager.RINGER_MODE_VIBRATE
+import android.media.AudioManager.STREAM_RING
 import android.os.VibrationEffect
 import android.widget.Toast
 import com.android.internal.R as internalR
 import com.android.settingslib.Utils
+import com.android.settingslib.notification.domain.interactor.NotificationsSoundPolicyInteractor
+import com.android.settingslib.volume.shared.model.AudioStream
 import com.android.settingslib.volume.shared.model.RingerMode
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
@@ -57,7 +60,8 @@
     @Application private val applicationContext: Context,
     @VolumeDialog private val coroutineScope: CoroutineScope,
     @Background private val backgroundDispatcher: CoroutineDispatcher,
-    private val interactor: VolumeDialogRingerInteractor,
+    soundPolicyInteractor: NotificationsSoundPolicyInteractor,
+    private val ringerInteractor: VolumeDialogRingerInteractor,
     private val vibrator: VibratorHelper,
     private val volumeDialogLogger: VolumeDialogLogger,
     private val visibilityInteractor: VolumeDialogVisibilityInteractor,
@@ -66,10 +70,14 @@
     private val drawerState = MutableStateFlow<RingerDrawerState>(RingerDrawerState.Initial)
 
     val ringerViewModel: StateFlow<RingerViewModelState> =
-        combine(interactor.ringerModel, drawerState) { ringerModel, state ->
+        combine(
+                soundPolicyInteractor.isZenMuted(AudioStream(STREAM_RING)),
+                ringerInteractor.ringerModel,
+                drawerState,
+            ) { isZenMuted, ringerModel, state ->
                 level = ringerModel.level
                 levelMax = ringerModel.levelMax
-                ringerModel.toViewModel(state)
+                ringerModel.toViewModel(state, isZenMuted)
             }
             .flowOn(backgroundDispatcher)
             .stateIn(coroutineScope, SharingStarted.Eagerly, RingerViewModelState.Unavailable)
@@ -90,7 +98,7 @@
             Events.writeEvent(Events.EVENT_RINGER_TOGGLE, ringerMode.value)
             provideTouchFeedback(ringerMode)
             maybeShowToast(ringerMode)
-            interactor.setRingerMode(ringerMode)
+            ringerInteractor.setRingerMode(ringerMode)
         }
         visibilityInteractor.resetDismissTimeout()
         drawerState.value =
@@ -113,7 +121,7 @@
     private fun provideTouchFeedback(ringerMode: RingerMode) {
         when (ringerMode.value) {
             RINGER_MODE_NORMAL -> {
-                interactor.scheduleTouchFeedback()
+                ringerInteractor.scheduleTouchFeedback()
                 null
             }
             RINGER_MODE_SILENT -> VibrationEffect.get(VibrationEffect.EFFECT_CLICK)
@@ -123,7 +131,8 @@
     }
 
     private fun VolumeDialogRingerModel.toViewModel(
-        drawerState: RingerDrawerState
+        drawerState: RingerDrawerState,
+        isZenMuted: Boolean,
     ): RingerViewModelState {
         val currentIndex = availableModes.indexOf(currentRingerMode)
         if (currentIndex == -1) {
@@ -132,10 +141,11 @@
         return if (currentIndex == -1 || isSingleVolume) {
             RingerViewModelState.Unavailable
         } else {
-            toButtonViewModel(currentRingerMode, isSelectedButton = true)?.let {
+            toButtonViewModel(currentRingerMode, isZenMuted, isSelectedButton = true)?.let {
                 RingerViewModelState.Available(
                     RingerViewModel(
-                        availableButtons = availableModes.map { mode -> toButtonViewModel(mode) },
+                        availableButtons =
+                            availableModes.map { mode -> toButtonViewModel(mode, isZenMuted) },
                         currentButtonIndex = currentIndex,
                         selectedButton = it,
                         drawerState = drawerState,
@@ -147,6 +157,7 @@
 
     private fun VolumeDialogRingerModel.toButtonViewModel(
         ringerMode: RingerMode,
+        isZenMuted: Boolean,
         isSelectedButton: Boolean = false,
     ): RingerButtonViewModel? {
         return when (ringerMode.value) {
@@ -176,7 +187,7 @@
                 )
             RINGER_MODE_NORMAL ->
                 when {
-                    isMuted && isEnabled ->
+                    isMuted && !isZenMuted ->
                         RingerButtonViewModel(
                             imageResId =
                                 if (isSelectedButton) {
@@ -226,7 +237,7 @@
 
     private fun maybeShowToast(ringerMode: RingerMode) {
         coroutineScope.launch {
-            val seenToastCount = interactor.getToastCount()
+            val seenToastCount = ringerInteractor.getToastCount()
             if (seenToastCount > SHOW_RINGER_TOAST_COUNT) {
                 return@launch
             }
@@ -260,7 +271,7 @@
                         )
                 }
             toastText?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_SHORT).show() }
-            interactor.updateToastCount(seenToastCount)
+            ringerInteractor.updateToastCount(seenToastCount)
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
index e52bad9..f305246 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
@@ -18,11 +18,12 @@
 
 import android.animation.Animator
 import android.animation.ObjectAnimator
+import android.annotation.SuppressLint
 import android.view.View
 import android.view.animation.DecelerateInterpolator
 import com.android.systemui.res.R
-import com.android.systemui.volume.dialog.shared.model.VolumeDialogStreamModel
 import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
+import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSliderStateModel
 import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSliderViewModel
 import com.android.systemui.volume.dialog.ui.utils.JankListenerFactory
 import com.android.systemui.volume.dialog.ui.utils.awaitAnimation
@@ -48,24 +49,27 @@
         val sliderView: Slider =
             view.requireViewById<Slider>(R.id.volume_dialog_slider).apply {
                 labelBehavior = LabelFormatter.LABEL_GONE
+                trackIconActiveColor = trackInactiveTintList
             }
         sliderView.addOnChangeListener { _, value, fromUser ->
             viewModel.setStreamVolume(value.roundToInt(), fromUser)
         }
 
-        viewModel.model.onEach { it.bindToSlider(sliderView) }.launchIn(this)
+        viewModel.state.onEach { it.bindToSlider(sliderView) }.launchIn(this)
     }
 
-    private suspend fun VolumeDialogStreamModel.bindToSlider(slider: Slider) {
+    @SuppressLint("UseCompatLoadingForDrawables")
+    private suspend fun VolumeDialogSliderStateModel.bindToSlider(slider: Slider) {
         with(slider) {
-            valueFrom = levelMin.toFloat()
-            valueTo = levelMax.toFloat()
+            valueFrom = minValue
+            valueTo = maxValue
             // coerce the current value to the new value range before animating it
             value = value.coerceIn(valueFrom, valueTo)
             setValueAnimated(
-                level.toFloat(),
+                value,
                 jankListenerFactory.update(this, PROGRESS_CHANGE_ANIMATION_DURATION_MS),
             )
+            trackIconActiveEnd = context.getDrawable(iconRes)
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProvider.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProvider.kt
new file mode 100644
index 0000000..5c39b6f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProvider.kt
@@ -0,0 +1,122 @@
+/*
+ * 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.volume.dialog.sliders.ui.viewmodel
+
+import android.media.AudioManager
+import androidx.annotation.DrawableRes
+import com.android.settingslib.notification.domain.interactor.NotificationsSoundPolicyInteractor
+import com.android.settingslib.volume.domain.interactor.AudioVolumeInteractor
+import com.android.settingslib.volume.shared.model.AudioStream
+import com.android.settingslib.volume.shared.model.RingerMode
+import com.android.systemui.res.R
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flowOf
+
+class VolumeDialogSliderIconProvider
+@Inject
+constructor(
+    private val notificationsSoundPolicyInteractor: NotificationsSoundPolicyInteractor,
+    private val audioVolumeInteractor: AudioVolumeInteractor,
+) {
+
+    @DrawableRes
+    fun getStreamIcon(
+        stream: Int,
+        level: Int,
+        levelMin: Int,
+        levelMax: Int,
+        isMuted: Boolean,
+        isRoutedToBluetooth: Boolean,
+    ): Flow<Int> {
+        return combine(
+            notificationsSoundPolicyInteractor.isZenMuted(AudioStream(stream)),
+            ringerModeForStream(stream),
+        ) { isZenMuted, ringerMode ->
+            val isStreamOffline = level == 0 || isMuted
+            if (isZenMuted) {
+                // TODO(b/372466264) use icon for the corresponding zenmode
+                return@combine com.android.internal.R.drawable.ic_qs_dnd
+            }
+            when (ringerMode?.value) {
+                AudioManager.RINGER_MODE_VIBRATE ->
+                    return@combine R.drawable.ic_volume_ringer_vibrate
+                AudioManager.RINGER_MODE_SILENT -> return@combine R.drawable.ic_ring_volume_off
+            }
+            if (isRoutedToBluetooth) {
+                return@combine if (stream == AudioManager.STREAM_VOICE_CALL) {
+                    R.drawable.ic_volume_bt_sco
+                } else {
+                    if (isStreamOffline) {
+                        R.drawable.ic_volume_media_bt_mute
+                    } else {
+                        R.drawable.ic_volume_media_bt
+                    }
+                }
+            }
+
+            return@combine if (isStreamOffline) {
+                getMutedIconForStream(stream) ?: getIconForStream(stream)
+            } else {
+                if (level < (levelMax + levelMin) / 2) {
+                    // This icon is different on TV
+                    R.drawable.ic_volume_media_low
+                } else {
+                    getIconForStream(stream)
+                }
+            }
+        }
+    }
+
+    @DrawableRes
+    private fun getMutedIconForStream(stream: Int): Int? {
+        return when (stream) {
+            AudioManager.STREAM_MUSIC -> R.drawable.ic_volume_media_mute
+            AudioManager.STREAM_NOTIFICATION -> R.drawable.ic_volume_ringer_mute
+            AudioManager.STREAM_ALARM -> R.drawable.ic_volume_alarm_mute
+            AudioManager.STREAM_SYSTEM -> R.drawable.ic_volume_system_mute
+            else -> null
+        }
+    }
+
+    @DrawableRes
+    private fun getIconForStream(stream: Int): Int {
+        return when (stream) {
+            AudioManager.STREAM_ACCESSIBILITY -> R.drawable.ic_volume_accessibility
+            AudioManager.STREAM_MUSIC -> R.drawable.ic_volume_media
+            AudioManager.STREAM_RING -> R.drawable.ic_ring_volume
+            AudioManager.STREAM_NOTIFICATION -> R.drawable.ic_volume_ringer
+            AudioManager.STREAM_ALARM -> R.drawable.ic_alarm
+            AudioManager.STREAM_VOICE_CALL -> com.android.internal.R.drawable.ic_phone
+            AudioManager.STREAM_SYSTEM -> R.drawable.ic_volume_system
+            else -> error("Unsupported stream: $stream")
+        }
+    }
+
+    /**
+     * Emits [RingerMode] for the [stream] if it's affecting it and null when [RingerMode] doesn't
+     * affect the [stream]
+     */
+    private fun ringerModeForStream(stream: Int): Flow<RingerMode?> {
+        return if (stream == AudioManager.STREAM_RING) {
+            audioVolumeInteractor.ringerMode
+        } else {
+            flowOf(null)
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderStateModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderStateModel.kt
new file mode 100644
index 0000000..5750c04
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderStateModel.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.volume.dialog.sliders.ui.viewmodel
+
+import androidx.annotation.DrawableRes
+import com.android.systemui.volume.dialog.shared.model.VolumeDialogStreamModel
+
+data class VolumeDialogSliderStateModel(
+    val minValue: Float,
+    val maxValue: Float,
+    val value: Float,
+    @DrawableRes val iconRes: Int,
+)
+
+fun VolumeDialogStreamModel.toStateModel(@DrawableRes iconRes: Int): VolumeDialogSliderStateModel {
+    return VolumeDialogSliderStateModel(
+        minValue = levelMin.toFloat(),
+        value = level.toFloat(),
+        maxValue = levelMax.toFloat(),
+        iconRes = iconRes,
+    )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
index 6dd5b63..2d56524 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
@@ -32,7 +32,9 @@
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.mapLatest
 import kotlinx.coroutines.flow.stateIn
 
@@ -56,12 +58,12 @@
     private val interactor: VolumeDialogSliderInteractor,
     private val visibilityInteractor: VolumeDialogVisibilityInteractor,
     @VolumeDialog private val coroutineScope: CoroutineScope,
+    private val volumeDialogSliderIconProvider: VolumeDialogSliderIconProvider,
     private val systemClock: SystemClock,
 ) {
 
     private val userVolumeUpdates = MutableStateFlow<VolumeUpdate?>(null)
-
-    val model: Flow<VolumeDialogStreamModel> =
+    private val model: Flow<VolumeDialogStreamModel> =
         interactor.slider
             .filter {
                 val lastVolumeUpdateTime = userVolumeUpdates.value?.timestampMillis ?: 0
@@ -70,6 +72,21 @@
             .stateIn(coroutineScope, SharingStarted.Eagerly, null)
             .filterNotNull()
 
+    val state: Flow<VolumeDialogSliderStateModel> =
+        model.flatMapLatest { streamModel ->
+            with(streamModel) {
+                    volumeDialogSliderIconProvider.getStreamIcon(
+                        stream = stream,
+                        level = level,
+                        levelMin = levelMin,
+                        levelMax = levelMax,
+                        isMuted = muted,
+                        isRoutedToBluetooth = routedToBluetooth,
+                    )
+                }
+                .map { icon -> streamModel.toStateModel(icon) }
+        }
+
     init {
         userVolumeUpdates
             .filterNotNull()
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 02747d7..6c4a853 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
@@ -80,10 +80,10 @@
                     label = label,
                     labelColor =
                         if (Flags.volumeRedesign()) {
-                            Color.Attribute(com.android.internal.R.attr.materialColorOnSurface)
+                            Color.Resource(com.android.internal.R.color.materialColorOnSurface)
                         } else {
-                            Color.Attribute(
-                                com.android.internal.R.attr.materialColorOnSurfaceVariant
+                            Color.Resource(
+                                com.android.internal.R.color.materialColorOnSurfaceVariant
                             )
                         },
                     deviceName =
@@ -96,10 +96,10 @@
                         },
                     deviceNameColor =
                         if (mediaOutputModel.canOpenAudioSwitcher) {
-                            Color.Attribute(com.android.internal.R.attr.materialColorOnSurface)
+                            Color.Resource(com.android.internal.R.color.materialColorOnSurface)
                         } else {
-                            Color.Attribute(
-                                com.android.internal.R.attr.materialColorOnSurfaceVariant
+                            Color.Resource(
+                                com.android.internal.R.color.materialColorOnSurfaceVariant
                             )
                         },
                 )
@@ -126,32 +126,32 @@
                         iconColor =
                             if (mediaOutputModel.canOpenAudioSwitcher) {
                                 if (Flags.volumeRedesign()) {
-                                    Color.Attribute(
-                                        com.android.internal.R.attr.materialColorOnPrimary
+                                    Color.Resource(
+                                        com.android.internal.R.color.materialColorOnPrimary
                                     )
                                 } else {
-                                    Color.Attribute(
-                                        com.android.internal.R.attr.materialColorSurface
+                                    Color.Resource(
+                                        com.android.internal.R.color.materialColorSurface
                                     )
                                 }
                             } else {
-                                Color.Attribute(
-                                    com.android.internal.R.attr.materialColorSurfaceContainerHighest
+                                Color.Resource(
+                                    com.android.internal.R.color.materialColorSurfaceContainerHighest
                                 )
                             },
                         backgroundColor =
                             if (mediaOutputModel.canOpenAudioSwitcher) {
                                 if (Flags.volumeRedesign()) {
-                                    Color.Attribute(
-                                        com.android.internal.R.attr.materialColorPrimary
+                                    Color.Resource(
+                                        com.android.internal.R.color.materialColorPrimary
                                     )
                                 } else {
-                                    Color.Attribute(
-                                        com.android.internal.R.attr.materialColorSecondary
+                                    Color.Resource(
+                                        com.android.internal.R.color.materialColorSecondary
                                     )
                                 }
                             } else {
-                                Color.Attribute(com.android.internal.R.attr.materialColorOutline)
+                                Color.Resource(com.android.internal.R.color.materialColorOutline)
                             },
                     )
                 } else {
@@ -160,16 +160,16 @@
                         iconColor =
                             if (mediaOutputModel.canOpenAudioSwitcher) {
                                 if (Flags.volumeRedesign()) {
-                                    Color.Attribute(
-                                        com.android.internal.R.attr.materialColorPrimary
+                                    Color.Resource(
+                                        com.android.internal.R.color.materialColorPrimary
                                     )
                                 } else {
-                                    Color.Attribute(
-                                        com.android.internal.R.attr.materialColorOnSurfaceVariant
+                                    Color.Resource(
+                                        com.android.internal.R.color.materialColorOnSurfaceVariant
                                     )
                                 }
                             } else {
-                                Color.Attribute(com.android.internal.R.attr.materialColorOutline)
+                                Color.Resource(com.android.internal.R.color.materialColorOutline)
                             },
                         backgroundColor = Color.Loaded(GraphicsColor.TRANSPARENT),
                     )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java
index 50d0049..dddaabb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java
@@ -26,10 +26,12 @@
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.graphics.PointF;
+
 import android.testing.TestableLooper;
 import android.view.View;
 import android.view.ViewPropertyAnimator;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
 
 import androidx.dynamicanimation.animation.DynamicAnimation;
 import androidx.dynamicanimation.animation.FlingAnimation;
@@ -49,6 +51,7 @@
 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;
 
@@ -69,13 +72,17 @@
     @Rule
     public MockitoRule mockito = MockitoJUnit.rule();
 
+    @Mock
+    private AccessibilityManager mAccessibilityManager;
+
     @Before
     public void setUp() throws Exception {
         final WindowManager stubWindowManager = mContext.getSystemService(WindowManager.class);
         final MenuViewAppearance stubMenuViewAppearance = new MenuViewAppearance(mContext,
                 stubWindowManager);
         final SecureSettings secureSettings = TestUtils.mockSecureSettings();
-        final MenuViewModel stubMenuViewModel = new MenuViewModel(mContext, secureSettings);
+        final MenuViewModel stubMenuViewModel = new MenuViewModel(mContext, mAccessibilityManager,
+                secureSettings);
 
         mMenuView = spy(new MenuView(mContext, stubMenuViewModel, stubMenuViewAppearance,
                 secureSettings));
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 f4580c1..400b3b3 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
@@ -159,7 +159,8 @@
                 new WindowMetrics(mDisplayBounds, fakeDisplayInsets(), /* density = */ 0.0f));
         doReturn(mWindowMetrics).when(mStubWindowManager).getCurrentWindowMetrics();
 
-        mMenuViewModel = new MenuViewModel(mSpyContext, mSecureSettings);
+        mMenuViewModel = new MenuViewModel(
+                mSpyContext, mStubAccessibilityManager, mSecureSettings);
         MenuViewAppearance menuViewAppearance = new MenuViewAppearance(
                 mSpyContext, mStubWindowManager);
         mMenuView = spy(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt
index 4da7b2a..e035a02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt
@@ -64,9 +64,11 @@
             override fun executeOnDiskIO(runnable: Runnable) {
                 runnable.run()
             }
+
             override fun postToMainThread(runnable: Runnable) {
                 runnable.run()
             }
+
             override fun isMainThread(): Boolean {
                 return true
             }
@@ -805,4 +807,32 @@
         fakeExecutor.runAllReady()
         verify(mockController).unregisterCallback(any())
     }
+
+    @Test
+    fun positionUpdatedWhileStopped() {
+        // When playback is stopped at one position
+        val firstPosition = 200L
+        val state =
+            PlaybackState.Builder().run {
+                setState(PlaybackState.STATE_STOPPED, firstPosition, 1f)
+                build()
+            }
+        whenever(mockController.playbackState).thenReturn(state)
+        val captor = ArgumentCaptor.forClass(MediaController.Callback::class.java)
+        viewModel.updateController(mockController)
+        verify(mockController).registerCallback(captor.capture())
+        assertThat(viewModel.progress.value!!.elapsedTime).isEqualTo(firstPosition.toInt())
+
+        // And the state is updated with a new position
+        val secondPosition = 42L
+        val secondState =
+            PlaybackState.Builder().run {
+                setState(PlaybackState.STATE_STOPPED, secondPosition, 1f)
+                build()
+            }
+        captor.value.onPlaybackStateChanged(secondState)
+
+        // THEN then elapsed time should be updated
+        assertThat(viewModel.progress.value!!.elapsedTime).isEqualTo(secondPosition.toInt())
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
index d88d69d..fc720b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
@@ -22,7 +22,10 @@
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.semantics.SemanticsProperties
+import androidx.compose.ui.test.SemanticsMatcher
 import androidx.compose.ui.test.assert
+import androidx.compose.ui.test.filter
 import androidx.compose.ui.test.hasContentDescription
 import androidx.compose.ui.test.junit4.ComposeContentTestRule
 import androidx.compose.ui.test.junit4.createComposeRule
@@ -84,7 +87,7 @@
         }
         composeRule.waitForIdle()
 
-        listState.onStarted(TestEditTiles[0])
+        listState.onStarted(TestEditTiles[0], DragType.Add)
 
         // Tile is being dragged, it should be replaced with a placeholder
         composeRule.onNodeWithContentDescription("tileA").assertDoesNotExist()
@@ -110,8 +113,8 @@
         }
         composeRule.waitForIdle()
 
-        listState.onStarted(TestEditTiles[0])
-        listState.onMoved(1, false)
+        listState.onStarted(TestEditTiles[0], DragType.Add)
+        listState.onTargeting(1, false)
         listState.onDrop()
 
         // Available tiles should re-appear
@@ -137,7 +140,7 @@
         }
         composeRule.waitForIdle()
 
-        listState.onStarted(TestEditTiles[0])
+        listState.onStarted(TestEditTiles[0], DragType.Add)
         listState.movedOutOfBounds()
         listState.onDrop()
 
@@ -162,11 +165,11 @@
         }
         composeRule.waitForIdle()
 
-        listState.onStarted(createEditTile("newTile"))
+        listState.onStarted(createEditTile("newTile"), DragType.Add)
         // Insert after tileD, which is at index 4
         // [ a ] [ b ] [ c ] [ empty ]
         // [ tile d ] [ e ]
-        listState.onMoved(4, insertAfter = true)
+        listState.onTargeting(4, insertAfter = true)
         listState.onDrop()
 
         // Available tiles should re-appear
@@ -182,11 +185,14 @@
     }
 
     private fun ComposeContentTestRule.assertTileGridContainsExactly(specs: List<String>) {
-        onNodeWithTag(CURRENT_TILES_GRID_TEST_TAG).onChildren().apply {
-            fetchSemanticsNodes().forEachIndexed { index, _ ->
-                get(index).assert(hasContentDescription(specs[index]))
+        onNodeWithTag(CURRENT_TILES_GRID_TEST_TAG)
+            .onChildren()
+            .filter(SemanticsMatcher.keyIsDefined(SemanticsProperties.ContentDescription))
+            .apply {
+                fetchSemanticsNodes().forEachIndexed { index, _ ->
+                    get(index).assert(hasContentDescription(specs[index]))
+                }
             }
-        }
     }
 
     companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
index 9a924ed..d8d6f2e9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
@@ -4,9 +4,10 @@
 import android.os.Handler
 import android.os.Looper
 import android.os.UserManager
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
 import android.testing.TestableLooper
 import android.testing.TestableLooper.RunWithLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.internal.telephony.flags.Flags
@@ -22,8 +23,11 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
+import com.android.systemui.qs.flags.QsInCompose.isEnabled
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIconWithRes
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.policy.BluetoothController
 import com.android.systemui.util.mockito.any
@@ -41,11 +45,17 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
 @RunWithLooper(setAsMainLooper = true)
 @SmallTest
-class BluetoothTileTest : SysuiTestCase() {
+class BluetoothTileTest(flags: FlagsParameterization) : SysuiTestCase() {
+
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
+    }
 
     @Mock private lateinit var qsLogger: QSLogger
     @Mock private lateinit var qsHost: QSHost
@@ -81,7 +91,7 @@
                 qsLogger,
                 bluetoothController,
                 featureFlags,
-                bluetoothTileDialogViewModel
+                bluetoothTileDialogViewModel,
             )
 
         tile.initialize()
@@ -109,8 +119,7 @@
 
         tile.handleUpdateState(state, /* arg= */ null)
 
-        assertThat(state.icon)
-            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_off))
+        assertThat(state.icon).isEqualTo(createExpectedIcon(R.drawable.qs_bluetooth_icon_off))
     }
 
     @Test
@@ -121,8 +130,7 @@
 
         tile.handleUpdateState(state, /* arg= */ null)
 
-        assertThat(state.icon)
-            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_off))
+        assertThat(state.icon).isEqualTo(createExpectedIcon(R.drawable.qs_bluetooth_icon_off))
     }
 
     @Test
@@ -133,8 +141,7 @@
 
         tile.handleUpdateState(state, /* arg= */ null)
 
-        assertThat(state.icon)
-            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_on))
+        assertThat(state.icon).isEqualTo(createExpectedIcon(R.drawable.qs_bluetooth_icon_on))
     }
 
     @Test
@@ -145,8 +152,7 @@
 
         tile.handleUpdateState(state, /* arg= */ null)
 
-        assertThat(state.icon)
-            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_search))
+        assertThat(state.icon).isEqualTo(createExpectedIcon(R.drawable.qs_bluetooth_icon_search))
     }
 
     @Test
@@ -161,11 +167,10 @@
             .isEqualTo(
                 mContext.getString(
                     R.string.quick_settings_bluetooth_secondary_label_battery_level,
-                    Utils.formatPercentage(50)
+                    Utils.formatPercentage(50),
                 )
             )
-        verify(bluetoothController)
-            .addOnMetadataChangedListener(eq(cachedDevice), any(), any())
+        verify(bluetoothController).addOnMetadataChangedListener(eq(cachedDevice), any(), any())
     }
 
     @Test
@@ -186,7 +191,7 @@
             .isEqualTo(
                 mContext.getString(
                     R.string.quick_settings_bluetooth_secondary_label_battery_level,
-                    Utils.formatPercentage(25)
+                    Utils.formatPercentage(25),
                 )
             )
         verify(bluetoothController, times(1))
@@ -197,7 +202,7 @@
     fun handleClick_hasSatelliteFeatureButNoQsTileDialogAndClickIsProcessing_doNothing() {
         mSetFlagsRule.enableFlags(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
         `when`(featureFlags.isEnabled(com.android.systemui.flags.Flags.BLUETOOTH_QS_TILE_DIALOG))
-                .thenReturn(false)
+            .thenReturn(false)
         `when`(clickJob.isCompleted).thenReturn(false)
         tile.mClickJob = clickJob
 
@@ -210,7 +215,7 @@
     fun handleClick_noSatelliteFeatureAndNoQsTileDialog_directSetBtEnable() {
         mSetFlagsRule.disableFlags(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
         `when`(featureFlags.isEnabled(com.android.systemui.flags.Flags.BLUETOOTH_QS_TILE_DIALOG))
-                .thenReturn(false)
+            .thenReturn(false)
 
         tile.handleClick(null)
 
@@ -221,7 +226,7 @@
     fun handleClick_noSatelliteFeatureButHasQsTileDialog_showDialog() {
         mSetFlagsRule.disableFlags(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
         `when`(featureFlags.isEnabled(com.android.systemui.flags.Flags.BLUETOOTH_QS_TILE_DIALOG))
-                .thenReturn(true)
+            .thenReturn(true)
 
         tile.handleClick(null)
 
@@ -265,7 +270,7 @@
         qsLogger: QSLogger,
         bluetoothController: BluetoothController,
         featureFlags: FeatureFlagsClassic,
-        bluetoothTileDialogViewModel: BluetoothTileDialogViewModel
+        bluetoothTileDialogViewModel: BluetoothTileDialogViewModel,
     ) :
         BluetoothTile(
             qsHost,
@@ -279,13 +284,13 @@
             qsLogger,
             bluetoothController,
             featureFlags,
-            bluetoothTileDialogViewModel
+            bluetoothTileDialogViewModel,
         ) {
         var restrictionChecked: String? = null
 
         override fun checkIfRestrictionEnforcedByAdminOnly(
             state: QSTile.State?,
-            userRestriction: String?
+            userRestriction: String?,
         ) {
             restrictionChecked = userRestriction
         }
@@ -321,7 +326,7 @@
     fun listenToDeviceMetadata(
         state: QSTile.BooleanState,
         cachedDevice: CachedBluetoothDevice,
-        batteryLevel: Int
+        batteryLevel: Int,
     ) {
         val btDevice = mock<BluetoothDevice>()
         whenever(cachedDevice.device).thenReturn(btDevice)
@@ -332,4 +337,20 @@
         addConnectedDevice(cachedDevice)
         tile.handleUpdateState(state, /* arg= */ null)
     }
+
+    private fun createExpectedIcon(resId: Int): QSTile.Icon {
+        return if (isEnabled) {
+            DrawableIconWithRes(mContext.getDrawable(resId), resId)
+        } else {
+            QSTileImpl.ResourceIcon.get(resId)
+        }
+    }
+
+    companion object {
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+        }
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
index 6a43a61..55fb6da 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
@@ -21,15 +21,15 @@
 import android.content.SharedPreferences
 import android.os.Handler
 import android.platform.test.annotations.DisableFlags
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
 import android.provider.Settings
 import android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS
 import android.provider.Settings.Global.ZEN_MODE_OFF
 import android.testing.TestableLooper
 import android.view.ContextThemeWrapper
-import androidx.test.ext.junit.runners.AndroidJUnit4
 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.animation.DialogTransitionAnimator
 import com.android.systemui.animation.Expandable
@@ -39,14 +39,19 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
+import com.android.systemui.qs.flags.QsInCompose.isEnabled
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIconWithRes
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.policy.ZenModeController
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.nullable
 import com.android.systemui.util.settings.FakeSettings
 import com.android.systemui.util.settings.SecureSettings
 import com.google.common.truth.Truth.assertThat
+import java.io.File
 import org.junit.After
 import org.junit.Before
 import org.junit.Test
@@ -55,56 +60,55 @@
 import org.mockito.Mockito.anyBoolean
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
-import java.io.File
 import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
 @SmallTest
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @DisableFlags(android.app.Flags.FLAG_MODES_UI)
-class DndTileTest : SysuiTestCase() {
+class DndTileTest(flags: FlagsParameterization) : SysuiTestCase() {
 
     companion object {
         private const val DEFAULT_USER = 0
         private const val KEY = Settings.Secure.ZEN_DURATION
+
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+        }
     }
 
-    @Mock
-    private lateinit var qsHost: QSHost
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
+    }
 
-    @Mock
-    private lateinit var metricsLogger: MetricsLogger
+    @Mock private lateinit var qsHost: QSHost
 
-    @Mock
-    private lateinit var statusBarStateController: StatusBarStateController
+    @Mock private lateinit var metricsLogger: MetricsLogger
 
-    @Mock
-    private lateinit var activityStarter: ActivityStarter
+    @Mock private lateinit var statusBarStateController: StatusBarStateController
 
-    @Mock
-    private lateinit var qsLogger: QSLogger
+    @Mock private lateinit var activityStarter: ActivityStarter
 
-    @Mock
-    private lateinit var uiEventLogger: QsEventLogger
+    @Mock private lateinit var qsLogger: QSLogger
 
-    @Mock
-    private lateinit var zenModeController: ZenModeController
+    @Mock private lateinit var uiEventLogger: QsEventLogger
 
-    @Mock
-    private lateinit var sharedPreferences: SharedPreferences
+    @Mock private lateinit var zenModeController: ZenModeController
 
-    @Mock
-    private lateinit var mDialogTransitionAnimator: DialogTransitionAnimator
+    @Mock private lateinit var sharedPreferences: SharedPreferences
 
-    @Mock
-    private lateinit var hostDialog: Dialog
+    @Mock private lateinit var mDialogTransitionAnimator: DialogTransitionAnimator
 
-    @Mock
-    private lateinit var expandable: Expandable
+    @Mock private lateinit var hostDialog: Dialog
 
-    @Mock
-    private lateinit var controller: DialogTransitionAnimator.Controller
+    @Mock private lateinit var expandable: Expandable
+
+    @Mock private lateinit var controller: DialogTransitionAnimator.Controller
 
     private lateinit var secureSettings: SecureSettings
     private lateinit var testableLooper: TestableLooper
@@ -118,31 +122,32 @@
 
         whenever(qsHost.userId).thenReturn(DEFAULT_USER)
 
-        val wrappedContext = object : ContextWrapper(
-                ContextThemeWrapper(context, R.style.Theme_SystemUI_QuickSettings)
-        ) {
-            override fun getSharedPreferences(file: File?, mode: Int): SharedPreferences {
-                return sharedPreferences
+        val wrappedContext =
+            object :
+                ContextWrapper(ContextThemeWrapper(context, R.style.Theme_SystemUI_QuickSettings)) {
+                override fun getSharedPreferences(file: File?, mode: Int): SharedPreferences {
+                    return sharedPreferences
+                }
             }
-        }
         whenever(qsHost.context).thenReturn(wrappedContext)
         whenever(expandable.dialogTransitionController(any())).thenReturn(controller)
 
-        tile = DndTile(
-            qsHost,
-            uiEventLogger,
-            testableLooper.looper,
-            Handler(testableLooper.looper),
-            FalsingManagerFake(),
-            metricsLogger,
-            statusBarStateController,
-            activityStarter,
-            qsLogger,
-            zenModeController,
-            sharedPreferences,
-            secureSettings,
-            mDialogTransitionAnimator
-        )
+        tile =
+            DndTile(
+                qsHost,
+                uiEventLogger,
+                testableLooper.looper,
+                Handler(testableLooper.looper),
+                FalsingManagerFake(),
+                metricsLogger,
+                statusBarStateController,
+                activityStarter,
+                qsLogger,
+                zenModeController,
+                sharedPreferences,
+                secureSettings,
+                mDialogTransitionAnimator,
+            )
     }
 
     @After
@@ -222,7 +227,7 @@
 
         tile.handleUpdateState(state, /* arg= */ null)
 
-        assertThat(state.icon).isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_dnd_icon_off))
+        assertThat(state.icon).isEqualTo(createExpectedIcon(R.drawable.qs_dnd_icon_off))
     }
 
     @Test
@@ -232,6 +237,14 @@
 
         tile.handleUpdateState(state, /* arg= */ null)
 
-        assertThat(state.icon).isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_dnd_icon_on))
+        assertThat(state.icon).isEqualTo(createExpectedIcon(R.drawable.qs_dnd_icon_on))
+    }
+
+    private fun createExpectedIcon(resId: Int): QSTile.Icon {
+        return if (isEnabled) {
+            DrawableIconWithRes(mContext.getDrawable(resId), resId)
+        } else {
+            QSTileImpl.ResourceIcon.get(resId)
+        }
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
index 190d80f..5f63b15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
@@ -16,6 +16,10 @@
 
 package com.android.systemui.qs.tiles;
 
+import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf;
+
+import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX;
+
 import static junit.framework.TestCase.assertEquals;
 import static junit.framework.TestCase.assertFalse;
 import static junit.framework.TestCase.assertTrue;
@@ -32,12 +36,12 @@
 import android.content.pm.UserInfo;
 import android.os.Handler;
 import android.os.RemoteException;
+import android.platform.test.flag.junit.FlagsParameterization;
 import android.provider.Settings;
 import android.service.dreams.IDreamManager;
 import android.service.quicksettings.Tile;
 import android.testing.TestableLooper;
 
-import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
@@ -45,9 +49,11 @@
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.QsEventLogger;
+import com.android.systemui.qs.flags.QsInCompose;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.res.R;
@@ -63,11 +69,21 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-@RunWith(AndroidJUnit4.class)
+import java.util.List;
+
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+@RunWith(ParameterizedAndroidJunit4.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
 public class DreamTileTest extends SysuiTestCase {
 
+    @Parameters(name = "{0}")
+    public static List<FlagsParameterization> getParams() {
+        return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX);
+    }
+
     @Mock
     private ActivityStarter mActivityStarter;
     @Mock
@@ -101,6 +117,11 @@
     private final String mExpectedTileLabel = mContext.getResources().getString(
             R.string.quick_settings_screensaver_label);
 
+    public DreamTileTest(FlagsParameterization flags) {
+        super();
+        mSetFlagsRule.setFlagsParameterization(flags);
+    }
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -246,13 +267,13 @@
         dockIntent.putExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_DESK);
         receiver.onReceive(mContext, dockIntent);
         mTestableLooper.processAllMessages();
-        assertEquals(QSTileImpl.ResourceIcon.get(R.drawable.ic_qs_screen_saver),
+        assertEquals(createExpectedIcon(R.drawable.ic_qs_screen_saver),
                 dockedTile.getState().icon);
 
         dockIntent.putExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
         receiver.onReceive(mContext, dockIntent);
         mTestableLooper.processAllMessages();
-        assertEquals(QSTileImpl.ResourceIcon.get(R.drawable.ic_qs_screen_saver_undocked),
+        assertEquals(createExpectedIcon(R.drawable.ic_qs_screen_saver_undocked),
                 dockedTile.getState().icon);
 
         destroyTile(dockedTile);
@@ -268,6 +289,14 @@
         mTestableLooper.processAllMessages();
     }
 
+    private QSTile.Icon createExpectedIcon(int resId) {
+        if (QsInCompose.isEnabled()) {
+            return new QSTileImpl.DrawableIconWithRes(mContext.getDrawable(resId), resId);
+        } else {
+            return QSTileImpl.ResourceIcon.get(resId);
+        }
+    }
+
     private DreamTile constructTileForTest(boolean dreamSupported,
             boolean dreamOnlyEnabledForSystemUser) {
         return new DreamTile(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java
index 5bd6944..ba6c2dc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java
@@ -16,16 +16,20 @@
 
 package com.android.systemui.qs.tiles;
 
+import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf;
+
+import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import android.os.Handler;
+import android.platform.test.flag.junit.FlagsParameterization;
 import android.service.quicksettings.Tile;
 import android.testing.TestableLooper;
 
-import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
@@ -38,6 +42,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.QsEventLogger;
+import com.android.systemui.qs.flags.QsInCompose;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.res.R;
@@ -54,11 +59,21 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
-@RunWith(AndroidJUnit4.class)
+import java.util.List;
+
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+@RunWith(ParameterizedAndroidJunit4.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
 public class HotspotTileTest extends SysuiTestCase {
 
+    @Parameters(name = "{0}")
+    public static List<FlagsParameterization> getParams() {
+        return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX);
+    }
+
     @Rule
     public MockitoRule mRule = MockitoJUnit.rule();
     @Mock
@@ -74,6 +89,11 @@
     private HotspotTile mTile;
     private QSTile.BooleanState mState = new QSTile.BooleanState();
 
+    public HotspotTileTest(FlagsParameterization flags) {
+        super();
+        mSetFlagsRule.setFlagsParameterization(flags);
+    }
+
     @Before
     public void setUp() throws Exception {
         mTestableLooper = TestableLooper.get(this);
@@ -144,7 +164,7 @@
         mTile.handleUpdateState(state, /* arg= */ null);
 
         assertThat(state.icon)
-                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_hotspot_icon_off));
+                .isEqualTo(createExpectedIcon(R.drawable.qs_hotspot_icon_off));
     }
 
     @Test
@@ -156,7 +176,7 @@
         mTile.handleUpdateState(state, /* arg= */ null);
 
         assertThat(state.icon)
-                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_hotspot_icon_search));
+                .isEqualTo(createExpectedIcon(R.drawable.qs_hotspot_icon_search));
     }
 
     @Test
@@ -168,6 +188,14 @@
         mTile.handleUpdateState(state, /* arg= */ null);
 
         assertThat(state.icon)
-                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_hotspot_icon_on));
+                .isEqualTo(createExpectedIcon(R.drawable.qs_hotspot_icon_on));
+    }
+
+    private QSTile.Icon createExpectedIcon(int resId) {
+        if (QsInCompose.isEnabled()) {
+            return new QSTileImpl.DrawableIconWithRes(mContext.getDrawable(resId), resId);
+        } else {
+            return QSTileImpl.ResourceIcon.get(resId);
+        }
     }
 }
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 5ada2f3..b26f0a6 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
@@ -260,7 +260,8 @@
 
     @Test
     public void connectCarrierNetwork_mergedCarrierEntryCanConnect_connectAndCreateSysUiToast() {
-        when(mTelephonyManager.isDataEnabled()).thenReturn(true);
+        InternetDialogController spyController = spy(mInternetDialogController);
+        when(spyController.isMobileDataEnabled()).thenReturn(true);
         when(mKeyguardStateController.isUnlocked()).thenReturn(true);
         when(mConnectivityManager.getActiveNetwork()).thenReturn(mNetwork);
         when(mConnectivityManager.getNetworkCapabilities(mNetwork))
@@ -272,7 +273,7 @@
         mTestableResources.addOverride(R.string.wifi_wont_autoconnect_for_now,
             TOAST_MESSAGE_STRING);
 
-        mInternetDialogController.connectCarrierNetwork();
+        spyController.connectCarrierNetwork();
 
         verify(mMergedCarrierEntry).connect(null /* callback */, false /* showToast */);
         verify(mToastFactory).createToast(any(), any(), eq(TOAST_MESSAGE_STRING), anyString(),
@@ -281,11 +282,12 @@
 
     @Test
     public void connectCarrierNetwork_mergedCarrierEntryCanConnect_doNothingWhenSettingsOff() {
-        when(mTelephonyManager.isDataEnabled()).thenReturn(false);
-
+        InternetDialogController spyController = spy(mInternetDialogController);
+        when(spyController.isMobileDataEnabled()).thenReturn(false);
         mTestableResources.addOverride(R.string.wifi_wont_autoconnect_for_now,
             TOAST_MESSAGE_STRING);
-        mInternetDialogController.connectCarrierNetwork();
+
+        spyController.connectCarrierNetwork();
 
         verify(mMergedCarrierEntry, never()).connect(null /* callback */, false /* showToast */);
         verify(mToastFactory, never()).createToast(any(), any(), anyString(), anyString(), anyInt(),
@@ -294,12 +296,13 @@
 
     @Test
     public void connectCarrierNetwork_mergedCarrierEntryCanConnect_doNothingWhenKeyguardLocked() {
-        when(mTelephonyManager.isDataEnabled()).thenReturn(true);
+        InternetDialogController spyController = spy(mInternetDialogController);
+        when(spyController.isMobileDataEnabled()).thenReturn(true);
         when(mKeyguardStateController.isUnlocked()).thenReturn(false);
 
         mTestableResources.addOverride(R.string.wifi_wont_autoconnect_for_now,
             TOAST_MESSAGE_STRING);
-        mInternetDialogController.connectCarrierNetwork();
+        spyController.connectCarrierNetwork();
 
         verify(mMergedCarrierEntry, never()).connect(null /* callback */, false /* showToast */);
         verify(mToastFactory, never()).createToast(any(), any(), anyString(), anyString(), anyInt(),
@@ -308,7 +311,8 @@
 
     @Test
     public void connectCarrierNetwork_mergedCarrierEntryCanConnect_doNothingWhenMobileIsPrimary() {
-        when(mTelephonyManager.isDataEnabled()).thenReturn(true);
+        InternetDialogController spyController = spy(mInternetDialogController);
+        when(spyController.isMobileDataEnabled()).thenReturn(true);
         when(mKeyguardStateController.isUnlocked()).thenReturn(true);
         when(mConnectivityManager.getActiveNetwork()).thenReturn(mNetwork);
         when(mConnectivityManager.getNetworkCapabilities(mNetwork))
@@ -446,10 +450,9 @@
         when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
         spyController.onAccessPointsChanged(null /* accessPoints */);
 
-        doReturn(SUB_ID2).when(spyController).getActiveAutoSwitchNonDdsSubId();
+        doReturn(SUB_ID).when(spyController).getActiveAutoSwitchNonDdsSubId();
         doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState();
-        doReturn(mServiceState).when(mTelephonyManager).getServiceState();
-        doReturn(TelephonyManager.DATA_DISCONNECTED).when(mTelephonyManager).getDataState();
+        spyController.mSubIdServiceState.put(SUB_ID2, mServiceState);
 
         assertFalse(TextUtils.equals(spyController.getSubtitleText(false),
                 getResourcesString("all_network_unavailable")));
@@ -469,8 +472,7 @@
         spyController.onAccessPointsChanged(null /* accessPoints */);
 
         doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState();
-        doReturn(mServiceState).when(mTelephonyManager).getServiceState();
-        doReturn(TelephonyManager.DATA_DISCONNECTED).when(mTelephonyManager).getDataState();
+        spyController.mSubIdServiceState.put(SUB_ID, mServiceState);
 
         assertTrue(TextUtils.equals(spyController.getSubtitleText(false),
                 getResourcesString("all_network_unavailable")));
@@ -487,11 +489,10 @@
         fakeAirplaneModeEnabled(false);
         when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
         mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
+        InternetDialogController spyController = spy(mInternetDialogController);
 
         doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getState();
-        doReturn(mServiceState).when(mTelephonyManager).getServiceState();
-
-        when(mTelephonyManager.isDataEnabled()).thenReturn(false);
+        spyController.mSubIdServiceState.put(SUB_ID, mServiceState);
 
         assertThat(mInternetDialogController.getSubtitleText(false))
                 .isEqualTo(getResourcesString("non_carrier_network_unavailable"));
@@ -499,6 +500,9 @@
         // if the Wi-Fi disallow config, then don't return Wi-Fi related string.
         mInternetDialogController.mCanConfigWifi = false;
 
+        when(spyController.isMobileDataEnabled()).thenReturn(false);
+
+
         assertThat(mInternetDialogController.getSubtitleText(false))
                 .isNotEqualTo(getResourcesString("non_carrier_network_unavailable"));
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateTest.java
index 7b24233..300c9b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateTest.java
@@ -6,6 +6,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -23,8 +24,8 @@
 import android.widget.Switch;
 import android.widget.TextView;
 
-import androidx.test.annotation.UiThreadTest;
 import androidx.recyclerview.widget.RecyclerView;
+import androidx.test.annotation.UiThreadTest;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
@@ -40,8 +41,6 @@
 import com.android.systemui.util.time.FakeSystemClock;
 import com.android.wifitrackerlib.WifiEntry;
 
-import kotlinx.coroutines.CoroutineScope;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -52,6 +51,8 @@
 
 import java.util.List;
 
+import kotlinx.coroutines.CoroutineScope;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -127,7 +128,7 @@
                 .spyStatic(WifiEnterpriseRestrictionUtils.class)
                 .startMocking();
         when(WifiEnterpriseRestrictionUtils.isChangeWifiStateAllowed(mContext)).thenReturn(true);
-        when(mSystemUIDialogFactory.create(any(SystemUIDialog.Delegate.class)))
+        when(mSystemUIDialogFactory.create(any(SystemUIDialog.Delegate.class), eq(mContext)))
                 .thenReturn(mSystemUIDialog);
         when(mSystemUIDialog.getContext()).thenReturn(mContext);
         when(mSystemUIDialog.getWindow()).thenReturn(mWindow);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutListSearchTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutListSearchTest.java
index 63e56ee..8045a13 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutListSearchTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutListSearchTest.java
@@ -26,7 +26,6 @@
 
 import android.graphics.drawable.Icon;
 import android.os.Handler;
-import android.platform.test.annotations.EnableFlags;
 import android.view.KeyboardShortcutGroup;
 import android.view.KeyboardShortcutInfo;
 import android.view.WindowManager;
@@ -34,7 +33,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 
 import com.google.android.material.bottomsheet.BottomSheetDialog;
@@ -95,7 +93,6 @@
     }
 
     @Test
-    @EnableFlags(Flags.FLAG_VALIDATE_KEYBOARD_SHORTCUT_HELPER_ICON_URI)
     public void requestAppKeyboardShortcuts_callback_sanitisesIcons() {
         KeyboardShortcutGroup group = createKeyboardShortcutGroupForIconTests();
 
@@ -114,7 +111,6 @@
     }
 
     @Test
-    @EnableFlags(Flags.FLAG_VALIDATE_KEYBOARD_SHORTCUT_HELPER_ICON_URI)
     public void requestImeKeyboardShortcuts_callback_sanitisesIcons() {
         KeyboardShortcutGroup group = createKeyboardShortcutGroupForIconTests();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsTest.java
index 105cf16..20ecaf7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsTest.java
@@ -31,7 +31,6 @@
 import android.app.Dialog;
 import android.graphics.drawable.Icon;
 import android.os.Handler;
-import android.platform.test.annotations.EnableFlags;
 import android.view.KeyboardShortcutGroup;
 import android.view.KeyboardShortcutInfo;
 import android.view.WindowManager;
@@ -39,7 +38,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
@@ -131,7 +129,6 @@
     }
 
     @Test
-    @EnableFlags(Flags.FLAG_VALIDATE_KEYBOARD_SHORTCUT_HELPER_ICON_URI)
     public void requestAppKeyboardShortcuts_callback_sanitisesIcons() {
         KeyboardShortcutGroup group = createKeyboardShortcutGroupForIconTests();
         KeyboardShortcuts.toggle(mContext, DEVICE_ID);
@@ -143,7 +140,6 @@
     }
 
     @Test
-    @EnableFlags(Flags.FLAG_VALIDATE_KEYBOARD_SHORTCUT_HELPER_ICON_URI)
     public void requestImeKeyboardShortcuts_callback_sanitisesIcons() {
         KeyboardShortcutGroup group = createKeyboardShortcutGroupForIconTests();
         KeyboardShortcuts.toggle(mContext, DEVICE_ID);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 11b19f9..99467cb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -1275,6 +1275,37 @@
     }
 
     @Test
+    @EnableSceneContainer
+    public void testChildHeightUpdated_whenMaxDisplayedNotificationsSet_updatesStackHeight() {
+        ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
+        int maxNotifs = 1; // any non-zero limit
+        float stackTop = 100;
+        float stackCutoff = 1100;
+        mStackScroller.setStackTop(stackTop);
+        mStackScroller.setStackCutoff(stackCutoff);
+
+        // Given we have a limit on max displayed notifications
+        int stackHeightBeforeUpdate = 100;
+        when(mStackSizeCalculator.computeHeight(eq(mStackScroller), eq(maxNotifs), anyFloat()))
+                .thenReturn((float) stackHeightBeforeUpdate);
+        mStackScroller.setMaxDisplayedNotifications(maxNotifs);
+
+        // And the stack heights are set
+        assertThat(mStackScroller.getIntrinsicStackHeight()).isEqualTo(stackHeightBeforeUpdate);
+        assertThat(mAmbientState.getStackEndHeight()).isEqualTo(stackHeightBeforeUpdate);
+
+        // When a child changes its height
+        int stackHeightAfterUpdate = 300;
+        when(mStackSizeCalculator.computeHeight(eq(mStackScroller), eq(maxNotifs), anyFloat()))
+                .thenReturn((float) stackHeightAfterUpdate);
+        mStackScroller.onChildHeightChanged(row, /* needsAnimation = */ false);
+
+        // Then the stack heights are updated
+        assertThat(mStackScroller.getIntrinsicStackHeight()).isEqualTo(stackHeightAfterUpdate);
+        assertThat(mAmbientState.getStackEndHeight()).isEqualTo(stackHeightAfterUpdate);
+    }
+
+    @Test
     @DisableSceneContainer
     public void testSetMaxDisplayedNotifications_notifiesListeners() {
         ExpandableView.OnHeightChangedListener listener =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 6912eda..d157cf2d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -36,8 +36,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static kotlinx.coroutines.flow.FlowKt.flowOf;
-
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -56,6 +54,8 @@
 
 import static java.util.Collections.emptySet;
 
+import static kotlinx.coroutines.flow.FlowKt.flowOf;
+
 import android.app.ActivityManager;
 import android.app.IWallpaperManager;
 import android.app.NotificationManager;
@@ -138,6 +138,7 @@
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.power.domain.interactor.PowerInteractor;
+import com.android.systemui.qs.flags.QSComposeFragment;
 import com.android.systemui.res.R;
 import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor;
 import com.android.systemui.scene.domain.startable.ScrimStartable;
@@ -181,6 +182,7 @@
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
 import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.notification.init.NotificationsController;
 import com.android.systemui.statusbar.notification.interruption.AvalancheProvider;
 import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
@@ -198,7 +200,6 @@
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.ExtensionController;
-import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
 import com.android.systemui.statusbar.window.StatusBarWindowController;
@@ -217,10 +218,6 @@
 import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.startingsurface.StartingSurface;
 
-import dagger.Lazy;
-
-import kotlinx.coroutines.test.TestScope;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -237,6 +234,9 @@
 
 import javax.inject.Provider;
 
+import dagger.Lazy;
+import kotlinx.coroutines.test.TestScope;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 @RunWithLooper(setAsMainLooper = true)
@@ -667,6 +667,9 @@
         mCentralSurfaces.startKeyguard();
         mInitController.executePostInitTasks();
         mCentralSurfaces.registerCallbacks();
+        // Clear first invocations caused by registering flows with JavaAdapter
+        mTestScope.getTestScheduler().runCurrent();
+        clearInvocations(mScrimController);
     }
 
     @Test
@@ -1159,8 +1162,7 @@
 
     @Test
     @EnableSceneContainer
-    public void brightnesShowingChanged_flagEnabled_ScrimControllerNotified() {
-        mCentralSurfaces.registerCallbacks();
+    public void brightnesShowingChanged_sceneContainerFlagEnabled_ScrimControllerNotified() {
         final ScrimStartable scrimStartable = mKosmos.getScrimStartable();
         scrimStartable.start();
 
@@ -1178,9 +1180,25 @@
 
     @Test
     @DisableSceneContainer
-    public void brightnesShowingChanged_flagDisabled_ScrimControllerNotified() {
-        mCentralSurfaces.registerCallbacks();
+    @EnableFlags(QSComposeFragment.FLAG_NAME)
+    public void brightnesShowingChanged_qsUiRefactorFlagEnabled_ScrimControllerNotified() {
+        mBrightnessMirrorShowingInteractor.setMirrorShowing(true);
+        mTestScope.getTestScheduler().runCurrent();
+        verify(mScrimController, atLeastOnce()).legacyTransitionTo(ScrimState.BRIGHTNESS_MIRROR);
+        clearInvocations(mScrimController);
 
+        mBrightnessMirrorShowingInteractor.setMirrorShowing(false);
+        mTestScope.getTestScheduler().runCurrent();
+        ArgumentCaptor<ScrimState> captor = ArgumentCaptor.forClass(ScrimState.class);
+        // The default is to call the one with the callback argument
+        verify(mScrimController, atLeastOnce()).legacyTransitionTo(captor.capture(), any());
+        assertThat(captor.getValue()).isNotEqualTo(ScrimState.BRIGHTNESS_MIRROR);
+    }
+
+    @Test
+    @DisableSceneContainer
+    @DisableFlags(QSComposeFragment.FLAG_NAME)
+    public void brightnesShowingChanged_flagsDisabled_ScrimControllerNotified() {
         mBrightnessMirrorShowingInteractor.setMirrorShowing(true);
         mTestScope.getTestScheduler().runCurrent();
         verify(mScrimController, never()).legacyTransitionTo(ScrimState.BRIGHTNESS_MIRROR);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
index abdd797..0ba0aeb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
@@ -45,6 +45,7 @@
 import com.android.systemui.shade.ShadeLogger
 import com.android.systemui.shade.ShadeViewController
 import com.android.systemui.shade.StatusBarLongPressGestureDetector
+import com.android.systemui.shade.data.repository.fakeShadeDisplaysRepository
 import com.android.systemui.shade.display.StatusBarTouchShadeDisplayPolicy
 import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
 import com.android.systemui.statusbar.CommandQueue
@@ -77,6 +78,7 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.verifyNoMoreInteractions
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
@@ -86,6 +88,7 @@
     private val statusBarContentInsetsProvider = statusBarContentInsetsProviderStore.defaultDisplay
 
     private val fakeDarkIconDispatcher = kosmos.fakeDarkIconDispatcher
+    private val fakeShadeDisplaysRepository = kosmos.fakeShadeDisplaysRepository
     @Mock private lateinit var shadeViewController: ShadeViewController
     @Mock private lateinit var panelExpansionInteractor: PanelExpansionInteractor
     @Mock private lateinit var featureFlags: FeatureFlags
@@ -260,6 +263,64 @@
     }
 
     @Test
+    @DisableFlags(AconfigFlags.FLAG_STATUS_BAR_CONNECTED_DISPLAYS)
+    fun handleTouchEventFromStatusBar_statusBarConnectedDisplaysDisabled_viewReceivesEvent() {
+        `when`(centralSurfacesImpl.commandQueuePanelsEnabled).thenReturn(true)
+        `when`(shadeViewController.isViewEnabled).thenReturn(true)
+        fakeShadeDisplaysRepository.setDisplayId(SECONDARY_DISPLAY_ID)
+        val event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 2f, 0)
+
+        view.onTouchEvent(event)
+
+        verify(shadeViewController).handleExternalTouch(event)
+    }
+
+    @Test
+    @EnableFlags(
+        AconfigFlags.FLAG_STATUS_BAR_CONNECTED_DISPLAYS,
+        AconfigFlags.FLAG_SHADE_WINDOW_GOES_AROUND,
+    )
+    fun handleTouchEventFromStatusBar_statusBarConnectedDisplaysEnabled_shadeWindowGoesAroundEnabled_viewReceivesEvent() {
+        `when`(centralSurfacesImpl.commandQueuePanelsEnabled).thenReturn(true)
+        `when`(shadeViewController.isViewEnabled).thenReturn(true)
+        fakeShadeDisplaysRepository.setDisplayId(SECONDARY_DISPLAY_ID)
+        val event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 2f, 0)
+
+        view.onTouchEvent(event)
+
+        verify(shadeViewController).handleExternalTouch(event)
+    }
+
+    @Test
+    @EnableFlags(AconfigFlags.FLAG_STATUS_BAR_CONNECTED_DISPLAYS)
+    @DisableFlags(AconfigFlags.FLAG_SHADE_WINDOW_GOES_AROUND)
+    fun handleTouchEventFromStatusBar_touchOnShadeDisplay_statusBarConnectedDisplaysEnabled_shadeWindowGoesAroundDisabled_viewReceivesEvent() {
+        `when`(centralSurfacesImpl.commandQueuePanelsEnabled).thenReturn(true)
+        `when`(shadeViewController.isViewEnabled).thenReturn(true)
+        fakeShadeDisplaysRepository.setDisplayId(DISPLAY_ID)
+        val event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 2f, 0)
+
+        view.onTouchEvent(event)
+
+        verify(shadeViewController).handleExternalTouch(event)
+    }
+
+    @Test
+    @EnableFlags(AconfigFlags.FLAG_STATUS_BAR_CONNECTED_DISPLAYS)
+    @DisableFlags(AconfigFlags.FLAG_SHADE_WINDOW_GOES_AROUND)
+    fun handleTouchEventFromStatusBar_touchNotOnShadeDisplay_statusBarConnectedDisplaysEnabled_shadeWindowGoesAroundDisabled_viewDoesNotReceiveEvent() {
+        `when`(centralSurfacesImpl.commandQueuePanelsEnabled).thenReturn(true)
+        `when`(shadeViewController.isViewEnabled).thenReturn(true)
+        fakeShadeDisplaysRepository.setDisplayId(SECONDARY_DISPLAY_ID)
+        val event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 2f, 0)
+
+        view.onTouchEvent(event)
+
+        verify(shadeViewController).isViewEnabled
+        verifyNoMoreInteractions(shadeViewController)
+    }
+
+    @Test
     @DisableFlags(com.android.systemui.Flags.FLAG_STATUS_BAR_SWIPE_OVER_CHIP)
     fun handleInterceptTouchEventFromStatusBar_shadeReturnsFalse_flagOff_viewReturnsFalse() {
         `when`(shadeViewController.handleExternalInterceptTouch(any())).thenReturn(false)
@@ -432,6 +493,7 @@
                 fakeDarkIconDispatcher,
                 statusBarContentInsetsProviderStore,
                 Lazy { statusBarTouchShadeDisplayPolicy },
+                fakeShadeDisplaysRepository,
             )
             .create(view)
             .also { it.init() }
@@ -445,6 +507,7 @@
     }
 
     private companion object {
-        const val DISPLAY_ID = 1
+        const val DISPLAY_ID = 0
+        const val SECONDARY_DISPLAY_ID = 2
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 33a4b7e..38ddb3e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -45,8 +45,6 @@
 
 import android.animation.Animator;
 import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
@@ -154,7 +152,6 @@
     private final FakeKeyguardTransitionRepository mKeyguardTransitionRepository =
             mKosmos.getKeyguardTransitionRepository();
     @Mock private KeyguardInteractor mKeyguardInteractor;
-    @Mock private TypedArray mMockTypedArray;
 
     // TODO(b/204991468): Use a real PanelExpansionStateManager object once this bug is fixed. (The
     //   event-dispatch-on-registration pattern caused some of these unit tests to fail.)
@@ -236,12 +233,8 @@
     public void setup() {
         MockitoAnnotations.initMocks(this);
         mContext = spy(getContext());
-        when(mContext.obtainStyledAttributes(
-                new int[]{com.android.internal.R.attr.materialColorSurface}))
-                .thenReturn(mMockTypedArray);
-
-        when(mMockTypedArray.getColorStateList(anyInt()))
-                .thenAnswer((invocation) -> ColorStateList.valueOf(mSurfaceColor));
+        when(mContext.getColor(com.android.internal.R.color.materialColorSurface))
+                .thenAnswer(invocation -> mSurfaceColor);
 
         mScrimBehind = spy(new ScrimView(mContext));
         mScrimInFront = new ScrimView(mContext);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index 3e24fbe..b39e38b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -533,7 +533,7 @@
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         when(mOngoingCallController.hasOngoingCall()).thenReturn(true);
-        when(mHeadsUpAppearanceController.shouldBeVisible()).thenReturn(true);
+        when(mHeadsUpAppearanceController.shouldHeadsUpStatusBarBeVisible()).thenReturn(true);
 
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
@@ -775,7 +775,7 @@
                 /* hasPrimaryOngoingActivity= */ true,
                 /* hasSecondaryOngoingActivity= */ false,
                 /* shouldAnimate= */ false);
-        when(mHeadsUpAppearanceController.shouldBeVisible()).thenReturn(true);
+        when(mHeadsUpAppearanceController.shouldHeadsUpStatusBarBeVisible()).thenReturn(true);
 
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
@@ -792,7 +792,7 @@
                 /* hasPrimaryOngoingActivity= */ true,
                 /* hasSecondaryOngoingActivity= */ true,
                 /* shouldAnimate= */ false);
-        when(mHeadsUpAppearanceController.shouldBeVisible()).thenReturn(true);
+        when(mHeadsUpAppearanceController.shouldHeadsUpStatusBarBeVisible()).thenReturn(true);
 
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
@@ -1091,9 +1091,9 @@
 
   @Test
   @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
-  public void disable_headsUpShouldBeVisibleTrue_clockDisabled() {
+  public void disable_shouldHeadsUpStatusBarBeVisibleTrue_clockDisabled() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
-        when(mHeadsUpAppearanceController.shouldBeVisible()).thenReturn(true);
+        when(mHeadsUpAppearanceController.shouldHeadsUpStatusBarBeVisible()).thenReturn(true);
 
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
@@ -1102,9 +1102,9 @@
 
   @Test
   @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
-  public void disable_headsUpShouldBeVisibleFalse_clockNotDisabled() {
+  public void disable_shouldHeadsUpStatusBarBeVisibleFalse_clockNotDisabled() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
-        when(mHeadsUpAppearanceController.shouldBeVisible()).thenReturn(false);
+        when(mHeadsUpAppearanceController.shouldHeadsUpStatusBarBeVisible()).thenReturn(false);
 
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModelKosmos.kt
new file mode 100644
index 0000000..b407b1b
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModelKosmos.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.communal.ui.viewmodel
+
+import android.service.dream.dreamManager
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.statusbar.policy.batteryController
+
+val Kosmos.communalToDreamButtonViewModel by
+    Kosmos.Fixture {
+        CommunalToDreamButtonViewModel(
+            backgroundContext = testDispatcher,
+            batteryController = batteryController,
+            dreamManager = dreamManager,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
index 7ee9d84..d941fb0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
@@ -54,7 +54,7 @@
  * that kosmos instance
  */
 fun Kosmos.runTest(testBody: suspend Kosmos.() -> Unit) =
-    testScope.runTest { this@runTest.testBody() }
+    testScope.runTest testBody@{ this@runTest.testBody() }
 
 fun Kosmos.runCurrent() = testScope.runCurrent()
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/ActivityStarterKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/ActivityStarterKosmos.kt
index 0ec8d49..49bbbef 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/ActivityStarterKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/ActivityStarterKosmos.kt
@@ -17,6 +17,6 @@
 package com.android.systemui.plugins
 
 import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.util.mockito.mock
+import org.mockito.kotlin.mock
 
 var Kosmos.activityStarter by Kosmos.Fixture { mock<ActivityStarter>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
index d71bc31..49957f0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
@@ -18,6 +18,7 @@
 
 import android.content.res.mainResources
 import androidx.lifecycle.LifecycleCoroutineScope
+import com.android.internal.logging.uiEventLoggerFake
 import com.android.systemui.classifier.domain.interactor.falsingInteractor
 import com.android.systemui.common.ui.domain.interactor.configurationInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
@@ -68,6 +69,7 @@
                     qqsMediaHost,
                     qsMediaHost,
                     usingMediaInComposeFragment,
+                    uiEventLoggerFake,
                     lifecycleScope,
                 )
             }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt
index 86c3add..71408f6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt
@@ -17,9 +17,11 @@
 package com.android.systemui.qs.panels.ui.viewmodel
 
 import android.content.applicationContext
+import com.android.internal.logging.uiEventLoggerFake
 import com.android.systemui.common.ui.domain.interactor.configurationInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.qs.panels.domain.interactor.editTilesListInteractor
 import com.android.systemui.qs.panels.domain.interactor.gridLayoutMap
 import com.android.systemui.qs.panels.domain.interactor.gridLayoutTypeInteractor
@@ -35,10 +37,12 @@
             currentTilesInteractor,
             tilesAvailabilityInteractor,
             minimumTilesInteractor,
+            uiEventLoggerFake,
             configurationInteractor,
             applicationContext,
             infiniteGridLayout,
             applicationCoroutineScope,
+            testDispatcher,
             gridLayoutTypeInteractor,
             gridLayoutMap,
         )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorKosmos.kt
index db4df38..f2af619 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorKosmos.kt
@@ -17,25 +17,24 @@
 package com.android.systemui.shade.domain.interactor
 
 import android.content.mockedContext
-import android.view.mockWindowManager
+import android.window.WindowContext
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.ui.view.mockShadeRootView
 import com.android.systemui.shade.ShadeWindowLayoutParams
 import com.android.systemui.shade.data.repository.fakeShadeDisplaysRepository
 import java.util.Optional
+import org.mockito.kotlin.mock
 
-val Kosmos.shadeLayoutParams by Kosmos.Fixture {
-    ShadeWindowLayoutParams.create(mockedContext)
-}
+val Kosmos.shadeLayoutParams by Kosmos.Fixture { ShadeWindowLayoutParams.create(mockedContext) }
+
+val Kosmos.mockedWindowContext by Kosmos.Fixture { mock<WindowContext>() }
 val Kosmos.shadeDisplaysInteractor by
     Kosmos.Fixture {
         ShadeDisplaysInteractor(
             Optional.of(mockShadeRootView),
             fakeShadeDisplaysRepository,
-            mockedContext,
-            shadeLayoutParams,
-            mockWindowManager,
+            mockedWindowContext,
             testScope.backgroundScope,
             testScope.backgroundScope.coroutineContext,
         )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionControllerKosmos.kt
index e5a75d5..8865573 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionControllerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionControllerKosmos.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.
@@ -18,8 +18,14 @@
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.util.mockito.mock
+import org.mockito.kotlin.mock
+
+var Kosmos.lockscreenShadeKeyguardTransitionController by Fixture {
+    mock<LockscreenShadeKeyguardTransitionController>()
+}
 
 var Kosmos.lockscreenShadeKeyguardTransitionControllerFactory by Fixture {
-    mock<LockscreenShadeKeyguardTransitionController.Factory>()
+    LockscreenShadeKeyguardTransitionController.Factory {
+        lockscreenShadeKeyguardTransitionController
+    }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerKosmos.kt
index 2767980..fc52e45 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerKosmos.kt
@@ -18,8 +18,12 @@
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.util.mockito.mock
+import org.mockito.kotlin.mock
+
+var Kosmos.lockscreenShadeQsTransitionController by Fixture {
+    mock<LockscreenShadeQsTransitionController>()
+}
 
 var Kosmos.lockscreenShadeQsTransitionControllerFactory by Fixture {
-    mock<LockscreenShadeQsTransitionController.Factory>()
+    LockscreenShadeQsTransitionController.Factory { lockscreenShadeQsTransitionController }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerKosmos.kt
index 43e39c0..5523bd6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerKosmos.kt
@@ -18,8 +18,12 @@
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.util.mockito.mock
+import org.mockito.kotlin.mock
+
+var Kosmos.singleShadeLockScreenOverScroller by Fixture {
+    mock<SingleShadeLockScreenOverScroller>()
+}
 
 var Kosmos.singleShadeLockScreenOverScrollerFactory by Fixture {
-    mock<SingleShadeLockScreenOverScroller.Factory>()
+    SingleShadeLockScreenOverScroller.Factory { _ -> singleShadeLockScreenOverScroller }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerKosmos.kt
index 017371a..e491dff 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerKosmos.kt
@@ -18,8 +18,10 @@
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.util.mockito.mock
+import org.mockito.kotlin.mock
+
+var Kosmos.splitShadeLockScreenOverScroller by Fixture { mock<SplitShadeLockScreenOverScroller>() }
 
 var Kosmos.splitShadeLockScreenOverScrollerFactory by Fixture {
-    mock<SplitShadeLockScreenOverScroller.Factory>()
+    SplitShadeLockScreenOverScroller.Factory { _, _ -> splitShadeLockScreenOverScroller }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelKosmos.kt
index 4bcce86..d0c80c7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelKosmos.kt
@@ -19,8 +19,13 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
+import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
 
 val Kosmos.notifChipsViewModel: NotifChipsViewModel by
     Kosmos.Fixture {
-        NotifChipsViewModel(applicationCoroutineScope, statusBarNotificationChipsInteractor)
+        NotifChipsViewModel(
+            applicationCoroutineScope,
+            statusBarNotificationChipsInteractor,
+            headsUpNotificationInteractor,
+        )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeStatusBarModeRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeStatusBarModeRepository.kt
index 22f8767..3c2d004 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeStatusBarModeRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeStatusBarModeRepository.kt
@@ -47,6 +47,7 @@
     override val isInFullscreenMode = MutableStateFlow(false)
     override val statusBarAppearance = MutableStateFlow<StatusBarAppearance?>(null)
     override val statusBarMode = MutableStateFlow(StatusBarMode.TRANSPARENT)
+    override val ongoingProcessRequiresStatusBarVisible = MutableStateFlow(false)
 
     override fun showTransient() {
         isTransientShown.value = true
@@ -59,6 +60,9 @@
     override fun start() {}
 
     override fun stop() {}
+    override fun setOngoingProcessRequiresStatusBarVisible(requiredVisible: Boolean) {
+        ongoingProcessRequiresStatusBarVisible.value = requiredVisible
+    }
 
     override fun onStatusBarViewInitialized(component: HomeStatusBarComponent) {}
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/VisualInterruptionDecisionProviderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/VisualInterruptionDecisionProviderKosmos.kt
new file mode 100644
index 0000000..360e9e9
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/VisualInterruptionDecisionProviderKosmos.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider
+import org.mockito.kotlin.mock
+
+val Kosmos.visualInterruptionDecisionProvider by
+    Kosmos.Fixture { mock<VisualInterruptionDecisionProvider>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorKosmos.kt
index 4a249a8..88bf9a5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorKosmos.kt
@@ -42,6 +42,6 @@
             sensitiveNotificationProtectionController,
             deviceEntryInteractor,
             sceneInteractor,
-            testScope,
+            testScope.backgroundScope,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/repository/FakeHeadsUpRowRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/repository/FakeHeadsUpRowRepository.kt
index 7de22d8..4a692d2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/repository/FakeHeadsUpRowRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/repository/FakeHeadsUpRowRepository.kt
@@ -26,7 +26,8 @@
         elementKey: Any = Any(),
         isPinned: Boolean,
     ) : this(key = key, elementKey = elementKey) {
-        this.pinnedStatus.value = if (isPinned) PinnedStatus.PinnedBySystem else PinnedStatus.NotPinned
+        this.pinnedStatus.value =
+            if (isPinned) PinnedStatus.PinnedBySystem else PinnedStatus.NotPinned
     }
 
     constructor(
@@ -40,3 +41,10 @@
     override val pinnedStatus: MutableStateFlow<PinnedStatus> =
         MutableStateFlow(PinnedStatus.NotPinned)
 }
+
+/** Use this fake if you're using [UnconfinedTestDispatcher]. See b/383528592 for reasoning. */
+class UnconfinedFakeHeadsUpRowRepository(
+    override val key: String,
+    override val elementKey: Any = Any(),
+    override val pinnedStatus: MutableStateFlow<PinnedStatus>,
+) : HeadsUpRowRepository
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorKosmos.kt
new file mode 100644
index 0000000..768952d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import org.mockito.kotlin.mock
+
+val Kosmos.notificationAlertsInteractor by Kosmos.Fixture { mock<NotificationAlertsInteractor>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorKosmos.kt
index 51fb36f..9090e02 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorKosmos.kt
@@ -20,7 +20,9 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.log.logcatLogBuffer
+import com.android.systemui.statusbar.data.repository.fakeStatusBarModeRepository
 import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
+import com.android.systemui.statusbar.window.fakeStatusBarWindowControllerStore
 
 val Kosmos.ongoingCallInteractor: OngoingCallInteractor by
     Kosmos.Fixture {
@@ -28,6 +30,8 @@
           scope = applicationCoroutineScope,
           activeNotificationsInteractor = activeNotificationsInteractor,
           activityManagerRepository = activityManagerRepository,
+          statusBarModeRepositoryStore = fakeStatusBarModeRepository,
+          statusBarWindowControllerStore = fakeStatusBarWindowControllerStore,
           logBuffer = logcatLogBuffer("OngoingCallInteractorKosmos"),
       )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/KeyguardStateControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/KeyguardStateControllerKosmos.kt
index f19ac1e..26642d4 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/KeyguardStateControllerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/KeyguardStateControllerKosmos.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.statusbar.policy
 
 import com.android.systemui.kosmos.Kosmos
-import org.mockito.Mockito.mock
+import org.mockito.kotlin.mock
 
 var Kosmos.keyguardStateController: KeyguardStateController by
-    Kosmos.Fixture { mock(KeyguardStateController::class.java) }
+    Kosmos.Fixture { mock<KeyguardStateController>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/FakeStatusBarWindowController.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/FakeStatusBarWindowController.kt
index a110a49..09e6a0e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/FakeStatusBarWindowController.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/FakeStatusBarWindowController.kt
@@ -20,6 +20,7 @@
 import android.view.ViewGroup
 import com.android.systemui.animation.ActivityTransitionAnimator
 import com.android.systemui.fragments.FragmentHostManager
+import kotlinx.coroutines.flow.MutableStateFlow
 import java.util.Optional
 
 class FakeStatusBarWindowController : StatusBarWindowController {
@@ -30,6 +31,8 @@
     var isStopped = false
         private set
 
+    val ongoingProcessRequiresStatusBarVisible = MutableStateFlow(false)
+
     override val statusBarHeight: Int = 0
 
     override fun refreshStatusBarHeight() {}
@@ -57,5 +60,7 @@
 
     override fun setForceStatusBarVisible(forceStatusBarVisible: Boolean) {}
 
-    override fun setOngoingProcessRequiresStatusBarVisible(visible: Boolean) {}
+    override fun setOngoingProcessRequiresStatusBarVisible(visible: Boolean) {
+        ongoingProcessRequiresStatusBarVisible.value = visible
+    }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/ui/gesture/FakeVelocityTracker.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/ui/gesture/FakeVelocityTracker.kt
index f12089a..e767b87 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/ui/gesture/FakeVelocityTracker.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/ui/gesture/FakeVelocityTracker.kt
@@ -20,9 +20,9 @@
 import com.android.systemui.touchpad.tutorial.ui.gesture.Velocity
 import com.android.systemui.touchpad.tutorial.ui.gesture.VelocityTracker
 
-class FakeVelocityTracker : VelocityTracker {
+class FakeVelocityTracker(velocity: Float = 0f) : VelocityTracker {
 
-    private var fakeVelocity = Velocity(0f)
+    private var fakeVelocity = Velocity(velocity)
 
     override fun calculateVelocity(): Velocity {
         return fakeVelocity
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelKosmos.kt
index c8ba551..34661ce 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelKosmos.kt
@@ -21,6 +21,7 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.statusbar.notification.domain.interactor.notificationsSoundPolicyInteractor
 import com.android.systemui.volume.dialog.domain.interactor.volumeDialogVisibilityInteractor
 import com.android.systemui.volume.dialog.ringer.domain.volumeDialogRingerInteractor
 import com.android.systemui.volume.dialog.shared.volumeDialogLogger
@@ -31,7 +32,8 @@
             applicationContext = applicationContext,
             backgroundDispatcher = testDispatcher,
             coroutineScope = applicationCoroutineScope,
-            interactor = volumeDialogRingerInteractor,
+            soundPolicyInteractor = notificationsSoundPolicyInteractor,
+            ringerInteractor = volumeDialogRingerInteractor,
             vibrator = vibratorHelper,
             volumeDialogLogger = volumeDialogLogger,
             visibilityInteractor = volumeDialogVisibilityInteractor,
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/Combinators.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/Combinators.kt
index 8bf3a43..ae9b8c8 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/Combinators.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/Combinators.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.kairos
 
 import com.android.systemui.kairos.util.These
+import com.android.systemui.kairos.util.WithPrev
 import com.android.systemui.kairos.util.just
 import com.android.systemui.kairos.util.none
 import kotlinx.coroutines.flow.Flow
@@ -27,15 +28,18 @@
  * Returns a [TFlow] that emits the value sampled from the [Transactional] produced by each emission
  * of the original [TFlow], within the same transaction of the original emission.
  */
+@ExperimentalFrpApi
 fun <A> TFlow<Transactional<A>>.sampleTransactionals(): TFlow<A> = map { it.sample() }
 
 /** @see FrpTransactionScope.sample */
+@ExperimentalFrpApi
 fun <A, B, C> TFlow<A>.sample(
     state: TState<B>,
     transform: suspend FrpTransactionScope.(A, B) -> C,
 ): TFlow<C> = map { transform(it, state.sample()) }
 
 /** @see FrpTransactionScope.sample */
+@ExperimentalFrpApi
 fun <A, B, C> TFlow<A>.sample(
     transactional: Transactional<B>,
     transform: suspend FrpTransactionScope.(A, B) -> C,
@@ -50,6 +54,7 @@
  *
  * @see sample
  */
+@ExperimentalFrpApi
 fun <A, B, C> TFlow<A>.samplePromptly(
     state: TState<B>,
     transform: suspend FrpTransactionScope.(A, B) -> C,
@@ -70,19 +75,10 @@
         }
 
 /**
- * Returns a [TState] containing a map with a snapshot of the current state of each [TState] in the
- * original map.
- */
-fun <K, A> Map<K, TState<A>>.combineValues(): TState<Map<K, A>> =
-    asIterable()
-        .map { (k, state) -> state.map { v -> k to v } }
-        .combine()
-        .map { entries -> entries.toMap() }
-
-/**
  * Returns a cold [Flow] that, when collected, emits from this [TFlow]. [network] is needed to
  * transactionally connect to / disconnect from the [TFlow] when collection starts/stops.
  */
+@ExperimentalFrpApi
 fun <A> TFlow<A>.toColdConflatedFlow(network: FrpNetwork): Flow<A> =
     channelFlow { network.activateSpec { observe { trySend(it) } } }.conflate()
 
@@ -90,6 +86,7 @@
  * Returns a cold [Flow] that, when collected, emits from this [TState]. [network] is needed to
  * transactionally connect to / disconnect from the [TState] when collection starts/stops.
  */
+@ExperimentalFrpApi
 fun <A> TState<A>.toColdConflatedFlow(network: FrpNetwork): Flow<A> =
     channelFlow { network.activateSpec { observe { trySend(it) } } }.conflate()
 
@@ -99,6 +96,7 @@
  *
  * When collection is cancelled, so is the [FrpSpec]. This means all ongoing work is cleaned up.
  */
+@ExperimentalFrpApi
 @JvmName("flowSpecToColdConflatedFlow")
 fun <A> FrpSpec<TFlow<A>>.toColdConflatedFlow(network: FrpNetwork): Flow<A> =
     channelFlow { network.activateSpec { applySpec().observe { trySend(it) } } }.conflate()
@@ -109,6 +107,7 @@
  *
  * When collection is cancelled, so is the [FrpSpec]. This means all ongoing work is cleaned up.
  */
+@ExperimentalFrpApi
 @JvmName("stateSpecToColdConflatedFlow")
 fun <A> FrpSpec<TState<A>>.toColdConflatedFlow(network: FrpNetwork): Flow<A> =
     channelFlow { network.activateSpec { applySpec().observe { trySend(it) } } }.conflate()
@@ -117,6 +116,7 @@
  * Returns a cold [Flow] that, when collected, applies this [Transactional] in a new transaction in
  * this [network], and then emits from the returned [TFlow].
  */
+@ExperimentalFrpApi
 @JvmName("transactionalFlowToColdConflatedFlow")
 fun <A> Transactional<TFlow<A>>.toColdConflatedFlow(network: FrpNetwork): Flow<A> =
     channelFlow { network.activateSpec { sample().observe { trySend(it) } } }.conflate()
@@ -125,6 +125,7 @@
  * Returns a cold [Flow] that, when collected, applies this [Transactional] in a new transaction in
  * this [network], and then emits from the returned [TState].
  */
+@ExperimentalFrpApi
 @JvmName("transactionalStateToColdConflatedFlow")
 fun <A> Transactional<TState<A>>.toColdConflatedFlow(network: FrpNetwork): Flow<A> =
     channelFlow { network.activateSpec { sample().observe { trySend(it) } } }.conflate()
@@ -135,6 +136,7 @@
  *
  * When collection is cancelled, so is the [FrpStateful]. This means all ongoing work is cleaned up.
  */
+@ExperimentalFrpApi
 @JvmName("statefulFlowToColdConflatedFlow")
 fun <A> FrpStateful<TFlow<A>>.toColdConflatedFlow(network: FrpNetwork): Flow<A> =
     channelFlow { network.activateSpec { applyStateful().observe { trySend(it) } } }.conflate()
@@ -145,11 +147,13 @@
  *
  * When collection is cancelled, so is the [FrpStateful]. This means all ongoing work is cleaned up.
  */
+@ExperimentalFrpApi
 @JvmName("statefulStateToColdConflatedFlow")
 fun <A> FrpStateful<TState<A>>.toColdConflatedFlow(network: FrpNetwork): Flow<A> =
     channelFlow { network.activateSpec { applyStateful().observe { trySend(it) } } }.conflate()
 
 /** Return a [TFlow] that emits from the original [TFlow] only when [state] is `true`. */
+@ExperimentalFrpApi
 fun <A> TFlow<A>.filter(state: TState<Boolean>): TFlow<A> = filter { state.sample() }
 
 private fun Iterable<Boolean>.allTrue() = all { it }
@@ -157,13 +161,15 @@
 private fun Iterable<Boolean>.anyTrue() = any { it }
 
 /** Returns a [TState] that is `true` only when all of [states] are `true`. */
+@ExperimentalFrpApi
 fun allOf(vararg states: TState<Boolean>): TState<Boolean> = combine(*states) { it.allTrue() }
 
 /** Returns a [TState] that is `true` when any of [states] are `true`. */
+@ExperimentalFrpApi
 fun anyOf(vararg states: TState<Boolean>): TState<Boolean> = combine(*states) { it.anyTrue() }
 
 /** Returns a [TState] containing the inverse of the Boolean held by the original [TState]. */
-fun not(state: TState<Boolean>): TState<Boolean> = state.mapCheapUnsafe { !it }
+@ExperimentalFrpApi fun not(state: TState<Boolean>): TState<Boolean> = state.mapCheapUnsafe { !it }
 
 /**
  * Represents a modal FRP sub-network.
@@ -177,6 +183,7 @@
  *
  * @see FrpStatefulMode
  */
+@ExperimentalFrpApi
 fun interface FrpBuildMode<out A> {
     /**
      * Invoked when this mode is enabled. Returns a value and a [TFlow] that signals a switch to a
@@ -192,6 +199,7 @@
  *
  * @see FrpBuildMode
  */
+@ExperimentalFrpApi
 val <A> FrpBuildMode<A>.compiledFrpSpec: FrpSpec<TState<A>>
     get() = frpSpec {
         var modeChangeEvents by TFlowLoop<FrpBuildMode<A>>()
@@ -215,6 +223,7 @@
  *
  * @see FrpBuildMode
  */
+@ExperimentalFrpApi
 fun interface FrpStatefulMode<out A> {
     /**
      * Invoked when this mode is enabled. Returns a value and a [TFlow] that signals a switch to a
@@ -230,6 +239,7 @@
  *
  * @see FrpBuildMode
  */
+@ExperimentalFrpApi
 val <A> FrpStatefulMode<A>.compiledStateful: FrpStateful<TState<A>>
     get() = statefully {
         var modeChangeEvents by TFlowLoop<FrpStatefulMode<A>>()
@@ -246,5 +256,18 @@
  * Runs [spec] in this [FrpBuildScope], and then re-runs it whenever [rebuildSignal] emits. Returns
  * a [TState] that holds the result of the currently-active [FrpSpec].
  */
+@ExperimentalFrpApi
 fun <A> FrpBuildScope.rebuildOn(rebuildSignal: TFlow<*>, spec: FrpSpec<A>): TState<A> =
     rebuildSignal.map { spec }.holdLatestSpec(spec)
+
+/**
+ * Like [stateChanges] but also includes the old value of this [TState].
+ *
+ * Shorthand for:
+ * ``` kotlin
+ *     stateChanges.map { WithPrev(previousValue = sample(), newValue = it) }
+ * ```
+ */
+@ExperimentalFrpApi
+val <A> TState<A>.transitions: TFlow<WithPrev<A, A>>
+    get() = stateChanges.map { WithPrev(previousValue = sample(), newValue = it) }
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/FrpBuildScope.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/FrpBuildScope.kt
index 4de6deb..209a402 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/FrpBuildScope.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/FrpBuildScope.kt
@@ -38,6 +38,7 @@
 import kotlinx.coroutines.flow.SharedFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.dropWhile
+import kotlinx.coroutines.flow.scan
 import kotlinx.coroutines.launch
 
 /** A function that modifies the FrpNetwork. */
@@ -596,6 +597,26 @@
     fun <A> Flow<A>.toTState(initialValue: A): TState<A> = toTFlow().hold(initialValue)
 
     /**
+     * Shorthand for:
+     * ```kotlin
+     * flow.scan(initialValue, operation).toTFlow().hold(initialValue)
+     * ```
+     */
+    @ExperimentalFrpApi
+    fun <A, B> Flow<A>.scanToTState(initialValue: B, operation: (B, A) -> B): TState<B> =
+        scan(initialValue, operation).toTFlow().hold(initialValue)
+
+    /**
+     * Shorthand for:
+     * ```kotlin
+     * flow.scan(initialValue) { a, f -> f(a) }.toTFlow().hold(initialValue)
+     * ```
+     */
+    @ExperimentalFrpApi
+    fun <A> Flow<(A) -> A>.scanToTState(initialValue: A): TState<A> =
+        scanToTState(initialValue) { a, f -> f(a) }
+
+    /**
      * Invokes [block] whenever this [TFlow] emits a value. [block] receives an [FrpBuildScope] that
      * can be used to make further modifications to the FRP network, and/or perform side-effects via
      * [effect].
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/FrpEffectScope.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/FrpEffectScope.kt
index be2eb43..b39dcc1 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/FrpEffectScope.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/FrpEffectScope.kt
@@ -22,16 +22,17 @@
 /**
  * Scope for external side-effects triggered by the Frp network. This still occurs within the
  * context of a transaction, so general suspending calls are disallowed to prevent blocking the
- * transaction. You can use [frpCoroutineScope] to [launch] new coroutines to perform long-running
- * asynchronous work. This scope is alive for the duration of the containing [FrpBuildScope] that
- * this side-effect scope is running in.
+ * transaction. You can use [frpCoroutineScope] to [launch][kotlinx.coroutines.launch] new
+ * coroutines to perform long-running asynchronous work. This scope is alive for the duration of the
+ * containing [FrpBuildScope] that this side-effect scope is running in.
  */
 @RestrictsSuspension
 @ExperimentalFrpApi
 interface FrpEffectScope : FrpTransactionScope {
     /**
      * A [CoroutineScope] whose lifecycle lives for as long as this [FrpEffectScope] is alive. This
-     * is generally until the [Job] returned by [FrpBuildScope.effect] is cancelled.
+     * is generally until the [Job][kotlinx.coroutines.Job] returned by [FrpBuildScope.effect] is
+     * cancelled.
      */
     @ExperimentalFrpApi val frpCoroutineScope: CoroutineScope
 
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/FrpNetwork.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/FrpNetwork.kt
index b688eaf..97252b4 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/FrpNetwork.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/FrpNetwork.kt
@@ -137,7 +137,7 @@
     override suspend fun <R> transact(block: suspend FrpTransactionScope.() -> R): R {
         val result = CompletableDeferred<R>(coroutineContext[Job])
         @Suppress("DeferredResultUnused")
-        network.transaction {
+        network.transaction("FrpNetwork.transact") {
             val buildScope =
                 BuildScopeImpl(
                     stateScope = StateScopeImpl(evalScope = this, endSignal = endSignal),
@@ -151,7 +151,7 @@
     override suspend fun activateSpec(spec: FrpSpec<*>) {
         val job =
             network
-                .transaction {
+                .transaction("FrpNetwork.activateSpec") {
                     val buildScope =
                         BuildScopeImpl(
                             stateScope = StateScopeImpl(evalScope = this, endSignal = endSignal),
@@ -166,7 +166,8 @@
     override fun <In, Out> coalescingMutableTFlow(
         coalesce: (old: Out, new: In) -> Out,
         getInitialValue: () -> Out,
-    ): CoalescingMutableTFlow<In, Out> = CoalescingMutableTFlow(coalesce, network, getInitialValue)
+    ): CoalescingMutableTFlow<In, Out> =
+        CoalescingMutableTFlow(null, coalesce, network, getInitialValue)
 
     override fun <T> mutableTFlow(): MutableTFlow<T> = MutableTFlow(network)
 
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/TFlow.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/TFlow.kt
index 7ba1aca..a175e2e 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/TFlow.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/TFlow.kt
@@ -467,12 +467,12 @@
 @ExperimentalFrpApi
 class CoalescingMutableTFlow<In, Out>
 internal constructor(
+    internal val name: String?,
     internal val coalesce: (old: Out, new: In) -> Out,
     internal val network: Network,
     private val getInitialValue: () -> Out,
     internal val impl: InputNode<Out> = InputNode(),
 ) : TFlow<Out>() {
-    internal val name: String? = null
     internal val storage = AtomicReference(false to getInitialValue())
 
     override fun toString(): String = "${this::class.simpleName}@$hashString"
@@ -490,7 +490,7 @@
         val (scheduled, _) = storage.getAndUpdate { (_, old) -> true to coalesce(old, value) }
         if (!scheduled) {
             @Suppress("DeferredResultUnused")
-            network.transaction {
+            network.transaction("CoalescingMutableTFlow${name?.let { "($name)" }.orEmpty()}.emit") {
                 impl.visit(this, storage.getAndSet(false to getInitialValue()).second)
             }
         }
@@ -520,16 +520,16 @@
     @ExperimentalFrpApi
     suspend fun emit(value: T) {
         coroutineScope {
+            var jobOrNull: Job? = null
             val newEmit =
                 async(start = CoroutineStart.LAZY) {
-                    network.transaction { impl.visit(this, value) }.await()
+                    jobOrNull?.join()
+                    network
+                        .transaction("MutableTFlow($name).emit") { impl.visit(this, value) }
+                        .await()
                 }
-            val jobOrNull = storage.getAndSet(newEmit)
-            if (jobOrNull?.isActive != true) {
-                newEmit.await()
-            } else {
-                jobOrNull.join()
-            }
+            jobOrNull = storage.getAndSet(newEmit)
+            newEmit.await()
         }
     }
 
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/TState.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/TState.kt
index a4c6956..80e7474 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/TState.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/TState.kt
@@ -121,7 +121,7 @@
 
 /**
  * Splits a [TState] of pairs into a pair of [TFlows][TState], where each returned [TState] holds
- * hald of the original.
+ * half of the original.
  *
  * Shorthand for:
  * ```kotlin
@@ -312,6 +312,57 @@
     )
 }
 
+/**
+ * Returns a [TState] whose value is generated with [transform] by combining the current values of
+ * each given [TState].
+ *
+ * @see TState.combineWith
+ */
+@ExperimentalFrpApi
+fun <A, B, C, D, E, Z> combine(
+    stateA: TState<A>,
+    stateB: TState<B>,
+    stateC: TState<C>,
+    stateD: TState<D>,
+    stateE: TState<E>,
+    transform: suspend FrpScope.(A, B, C, D, E) -> Z,
+): TState<Z> {
+    val operatorName = "combine"
+    val name = operatorName
+    return TStateInit(
+        init(name) {
+            coroutineScope {
+                val dl1: Deferred<TStateImpl<A>> = async {
+                    stateA.init.connect(evalScope = this@init)
+                }
+                val dl2: Deferred<TStateImpl<B>> = async {
+                    stateB.init.connect(evalScope = this@init)
+                }
+                val dl3: Deferred<TStateImpl<C>> = async {
+                    stateC.init.connect(evalScope = this@init)
+                }
+                val dl4: Deferred<TStateImpl<D>> = async {
+                    stateD.init.connect(evalScope = this@init)
+                }
+                val dl5: Deferred<TStateImpl<E>> = async {
+                    stateE.init.connect(evalScope = this@init)
+                }
+                zipStates(
+                    name,
+                    operatorName,
+                    dl1.await(),
+                    dl2.await(),
+                    dl3.await(),
+                    dl4.await(),
+                    dl5.await(),
+                ) { a, b, c, d, e ->
+                    NoScope.runInFrpScope { transform(a, b, c, d, e) }
+                }
+            }
+        }
+    )
+}
+
 /** Returns a [TState] by applying [transform] to the value held by the original [TState]. */
 @ExperimentalFrpApi
 fun <A, B> TState<A>.flatMap(transform: suspend FrpScope.(A) -> TState<B>): TState<B> {
@@ -367,7 +418,7 @@
  * @see selector
  */
 @ExperimentalFrpApi
-class TStateSelector<A>
+class TStateSelector<in A>
 internal constructor(
     private val upstream: TState<A>,
     private val groupedChanges: GroupedTFlow<A, Boolean>,
@@ -406,6 +457,7 @@
 
     private val input: CoalescingMutableTFlow<Deferred<T>, Deferred<T>?> =
         CoalescingMutableTFlow(
+            name = null,
             coalesce = { _, new -> new },
             network = network,
             getInitialValue = { null },
@@ -423,7 +475,7 @@
                 .cached()
         state = TStateSource(name, operatorName, initialValue, calm)
         @Suppress("DeferredResultUnused")
-        network.transaction {
+        network.transaction("MutableTState.init") {
             calm.activate(evalScope = this, downstream = Schedulable.S(state))?.let {
                 (connection, needsEval) ->
                 state.upstreamConnection = connection
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/debug/Debug.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/debug/Debug.kt
index 4f302a1..0674a2e 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/debug/Debug.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/debug/Debug.kt
@@ -31,6 +31,8 @@
 import com.android.systemui.kairos.util.Just
 import com.android.systemui.kairos.util.Maybe
 import com.android.systemui.kairos.util.None
+import com.android.systemui.kairos.util.flatMap
+import com.android.systemui.kairos.util.map
 import com.android.systemui.kairos.util.none
 import com.android.systemui.kairos.util.orElseGet
 
@@ -178,3 +180,24 @@
         is TStateSource -> getStorageUnsafe()
         is DerivedMapCheap<*, *> -> none
     }
+
+private fun <A> TStateImpl<A>.getUnsafeWithEpoch(): Maybe<Pair<A, Long>> =
+    when (this) {
+        is TStateDerived -> getCachedUnsafe().map { it to invalidatedEpoch }
+        is TStateSource -> getStorageUnsafe().map { it to writeEpoch }
+        is DerivedMapCheap<*, *> -> none
+    }
+
+/**
+ * Returns the current value held in this [TState], or [none] if the [TState] has not been
+ * initialized.
+ *
+ * The returned [Long] is the *epoch* at which the internal cache was last updated. This can be used
+ * to identify values which are out-of-date.
+ */
+fun <A> TState<A>.sampleUnsafe(): Maybe<Pair<A, Long>> =
+    when (this) {
+        is MutableTState -> tState.init.getUnsafe().flatMap { it.getUnsafeWithEpoch() }
+        is TStateInit -> init.getUnsafe().flatMap { it.getUnsafeWithEpoch() }
+        is TStateLoop -> this.init.getUnsafe().flatMap { it.getUnsafeWithEpoch() }
+    }
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/BuildScopeImpl.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/BuildScopeImpl.kt
index 90f1aea..7e63849 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/BuildScopeImpl.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/BuildScopeImpl.kt
@@ -34,9 +34,9 @@
 import com.android.systemui.kairos.groupByKey
 import com.android.systemui.kairos.init
 import com.android.systemui.kairos.internal.util.childScope
-import com.android.systemui.kairos.internal.util.launchOnCancel
 import com.android.systemui.kairos.internal.util.mapValuesParallel
 import com.android.systemui.kairos.launchEffect
+import com.android.systemui.kairos.mergeLeft
 import com.android.systemui.kairos.util.Just
 import com.android.systemui.kairos.util.Maybe
 import com.android.systemui.kairos.util.None
@@ -49,7 +49,6 @@
 import kotlin.coroutines.startCoroutine
 import kotlinx.coroutines.CompletableDeferred
 import kotlinx.coroutines.CompletableJob
-import kotlinx.coroutines.CoroutineName
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Deferred
 import kotlinx.coroutines.Job
@@ -86,8 +85,7 @@
         builder: suspend S.() -> Unit,
     ): TFlow<A> {
         var job: Job? = null
-        val stopEmitter = newStopEmitter()
-        val handle = this.job.invokeOnCompletion { stopEmitter.emit(Unit) }
+        val stopEmitter = newStopEmitter("buildTFlow")
         // Create a child scope that will be kept alive beyond the end of this transaction.
         val childScope = coroutineScope.childScope()
         lateinit var emitter: Pair<T, S>
@@ -99,7 +97,6 @@
                         reenterBuildScope(this@BuildScopeImpl, childScope).runInBuildScope {
                             launchEffect {
                                 builder(emitter.second)
-                                handle.dispose()
                                 stopEmitter.emit(Unit)
                             }
                         }
@@ -110,7 +107,7 @@
                 },
             )
         emitter = constructFlow(inputNode)
-        return with(frpScope) { emitter.first.takeUntil(stopEmitter) }
+        return with(frpScope) { emitter.first.takeUntil(mergeLeft(stopEmitter, endSignal)) }
     }
 
     private fun <T> tFlowInternal(builder: suspend FrpProducerScope<T>.() -> Unit): TFlow<T> =
@@ -134,7 +131,8 @@
     ): TFlow<Out> =
         buildTFlow(
             constructFlow = { inputNode ->
-                val flow = CoalescingMutableTFlow(coalesce, network, getInitialValue, inputNode)
+                val flow =
+                    CoalescingMutableTFlow(null, coalesce, network, getInitialValue, inputNode)
                 flow to
                     object : FrpCoalescingProducerScope<In> {
                         override fun emit(value: In) {
@@ -164,11 +162,13 @@
         val subRef = AtomicReference<Maybe<Output<A>>>(null)
         val childScope = coroutineScope.childScope()
         // When our scope is cancelled, deactivate this observer.
-        childScope.launchOnCancel(CoroutineName("TFlow.observeEffect")) {
+        childScope.coroutineContext.job.invokeOnCompletion {
             subRef.getAndSet(None)?.let { output ->
                 if (output is Just) {
                     @Suppress("DeferredResultUnused")
-                    network.transaction { scheduleDeactivation(output.value) }
+                    network.transaction("observeEffect cancelled") {
+                        scheduleDeactivation(output.value)
+                    }
                 }
             }
         }
@@ -215,7 +215,7 @@
                     } else if (needsEval) {
                         outputNode.schedule(evalScope = stateScope.evalScope)
                     }
-                } ?: childScope.cancel()
+                } ?: run { childScope.cancel() }
         }
         return childScope.coroutineContext.job
     }
@@ -229,10 +229,7 @@
                 "mapBuild",
                 mapImpl({ init.connect(evalScope = this) }) { spec ->
                         reenterBuildScope(outerScope = this@BuildScopeImpl, childScope)
-                            .runInBuildScope {
-                                val (result, _) = asyncScope { transform(spec) }
-                                result.get()
-                            }
+                            .runInBuildScope { transform(spec) }
                     }
                     .cached(),
             )
@@ -272,8 +269,9 @@
         return changes to FrpDeferredValue(initOut)
     }
 
-    private fun newStopEmitter(): CoalescingMutableTFlow<Unit, Unit> =
+    private fun newStopEmitter(name: String): CoalescingMutableTFlow<Unit, Unit> =
         CoalescingMutableTFlow(
+            name = name,
             coalesce = { _, _: Unit -> },
             network = network,
             getInitialValue = {},
@@ -299,17 +297,19 @@
     }
 
     private fun mutableChildBuildScope(): BuildScopeImpl {
-        val stopEmitter = newStopEmitter()
+        val stopEmitter = newStopEmitter("mutableChildBuildScope")
         val childScope = coroutineScope.childScope()
         childScope.coroutineContext.job.invokeOnCompletion { stopEmitter.emit(Unit) }
         // Ensure that once this transaction is done, the new child scope enters the completing
         // state (kept alive so long as there are child jobs).
-        scheduleOutput(
-            OneShot {
-                // TODO: don't like this cast
-                (childScope.coroutineContext.job as CompletableJob).complete()
-            }
-        )
+        // TODO: need to keep the scope alive if it's used to accumulate state.
+        //  Otherwise, stopEmitter will emit early, due to the call to complete().
+        //        scheduleOutput(
+        //            OneShot {
+        //                // TODO: don't like this cast
+        //                (childScope.coroutineContext.job as CompletableJob).complete()
+        //            }
+        //        )
         return BuildScopeImpl(
             stateScope = StateScopeImpl(evalScope = stateScope.evalScope, endSignal = stopEmitter),
             coroutineScope = childScope,
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Graph.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Graph.kt
index 3aec319..04ce5b6 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Graph.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Graph.kt
@@ -86,7 +86,7 @@
     @Volatile private var dirty_depthIsDirect = true
     @Volatile private var dirty_isIndirectRoot = false
 
-    suspend fun schedule(scheduler: Scheduler, node: MuxNode<*, *, *>) {
+    fun schedule(scheduler: Scheduler, node: MuxNode<*, *, *>) {
         if (dirty_depthIsDirect) {
             scheduler.schedule(dirty_directDepth, node)
         } else {
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/InternalScopes.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/InternalScopes.kt
index af864e6..69994ba 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/InternalScopes.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/InternalScopes.kt
@@ -66,8 +66,6 @@
 
     fun schedule(state: TStateSource<*>)
 
-    suspend fun schedule(node: MuxNode<*, *, *>)
-
     fun scheduleDeactivation(node: PushNode<*>)
 
     fun scheduleDeactivation(output: Output<*>)
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Mux.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Mux.kt
index f7ff15f..af68a1e 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Mux.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Mux.kt
@@ -188,6 +188,14 @@
     }
 
     abstract fun hasCurrentValueLocked(transactionStore: TransactionStore): Boolean
+
+    fun schedule(evalScope: EvalScope) {
+        // TODO: Potential optimization
+        //  Detect if this node is guaranteed to have a single upstream within this transaction,
+        //  then bypass scheduling it. Instead immediately schedule its downstream and treat this
+        //  MuxNode as a Pull (effectively making it a mapCheap).
+        depthTracker.schedule(evalScope.scheduler, this)
+    }
 }
 
 /** An input branch of a mux node, associated with a key. */
@@ -202,7 +210,7 @@
         val upstreamResult = upstream.getPushEvent(evalScope)
         if (upstreamResult is Just) {
             muxNode.upstreamData[key] = upstreamResult.value
-            evalScope.schedule(muxNode)
+            muxNode.schedule(evalScope)
         }
     }
 
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/MuxDeferred.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/MuxDeferred.kt
index 08bee85..3b9502a 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/MuxDeferred.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/MuxDeferred.kt
@@ -409,7 +409,7 @@
                 // Schedule for evaluation if any switched-in nodes have already emitted within
                 // this transaction.
                 if (muxNode.upstreamData.isNotEmpty()) {
-                    evalScope.schedule(muxNode)
+                    muxNode.schedule(evalScope)
                 }
                 return muxNode.takeUnless { muxNode.switchedIn.isEmpty() && !isIndirect }
             }
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/MuxPrompt.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/MuxPrompt.kt
index cdfafa9..b291c87 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/MuxPrompt.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/MuxPrompt.kt
@@ -75,7 +75,7 @@
             if (depthTracker.dirty_depthIncreased()) {
                 depthTracker.schedule(evalScope.compactor, node = this)
             }
-            evalScope.schedule(this)
+            schedule(evalScope)
         } else {
             val compactDownstream = depthTracker.isDirty()
             if (evalResult != null || compactDownstream) {
@@ -291,7 +291,7 @@
         val upstreamResult = upstream.getPushEvent(evalScope)
         if (upstreamResult is Just) {
             muxNode.patchData = upstreamResult.value
-            evalScope.schedule(muxNode)
+            muxNode.schedule(evalScope)
         }
     }
 
@@ -451,7 +451,7 @@
                     // Schedule for evaluation if any switched-in nodes or the patches node have
                     // already emitted within this transaction.
                     if (movingNode.patchData != null || movingNode.upstreamData.isNotEmpty()) {
-                        evalScope.schedule(movingNode)
+                        movingNode.schedule(evalScope)
                     }
 
                     return movingNode.takeUnless { it.patches == null && it.switchedIn.isEmpty() }
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Network.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Network.kt
index f0df89d..599b186 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Network.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Network.kt
@@ -81,11 +81,6 @@
         stateWrites.add(state)
     }
 
-    // TODO: weird that we have this *and* scheduler exposed
-    override suspend fun schedule(node: MuxNode<*, *, *>) {
-        scheduler.schedule(node.depthTracker.dirty_directDepth, node)
-    }
-
     override fun scheduleDeactivation(node: PushNode<*>) {
         deactivations.add(node)
     }
@@ -95,9 +90,7 @@
     }
 
     /** Listens for external events and starts FRP transactions. Runs forever. */
-    suspend fun runInputScheduler() = coroutineScope {
-        launch { scheduler.activate() }
-        launch { compactor.activate() }
+    suspend fun runInputScheduler() {
         val actions = mutableListOf<ScheduledAction<*>>()
         for (first in inputScheduleChan) {
             // Drain and conflate all transaction requests into a single transaction
@@ -125,12 +118,12 @@
     }
 
     /** Evaluates [block] inside of a new transaction when the network is ready. */
-    fun <R> transaction(block: suspend EvalScope.() -> R): Deferred<R> =
+    fun <R> transaction(reason: String, block: suspend EvalScope.() -> R): Deferred<R> =
         CompletableDeferred<R>(parent = coroutineScope.coroutineContext.job).also { onResult ->
             val job =
                 coroutineScope.launch {
                     inputScheduleChan.send(
-                        ScheduledAction(onStartTransaction = block, onResult = onResult)
+                        ScheduledAction(reason, onStartTransaction = block, onResult = onResult)
                     )
                 }
             onResult.invokeOnCompletion { job.cancel() }
@@ -229,6 +222,7 @@
 }
 
 internal class ScheduledAction<T>(
+    val reason: String,
     private val onResult: CompletableDeferred<T>? = null,
     private val onStartTransaction: suspend EvalScope.() -> T,
 ) {
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Scheduler.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Scheduler.kt
index 872fb7a..c12ef6a 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Scheduler.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Scheduler.kt
@@ -21,44 +21,34 @@
 import java.util.concurrent.ConcurrentHashMap
 import java.util.concurrent.PriorityBlockingQueue
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.channels.Channel
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.launch
 
 internal interface Scheduler {
-    suspend fun schedule(depth: Int, node: MuxNode<*, *, *>)
+    fun schedule(depth: Int, node: MuxNode<*, *, *>)
 
-    suspend fun scheduleIndirect(indirectDepth: Int, node: MuxNode<*, *, *>)
+    fun scheduleIndirect(indirectDepth: Int, node: MuxNode<*, *, *>)
 }
 
 internal class SchedulerImpl : Scheduler {
     val enqueued = ConcurrentHashMap<MuxNode<*, *, *>, Any>()
     val scheduledQ = PriorityBlockingQueue<Pair<Int, MuxNode<*, *, *>>>(16, compareBy { it.first })
-    val chan = Channel<Pair<Int, MuxNode<*, *, *>>>(Channel.UNLIMITED)
 
-    override suspend fun schedule(depth: Int, node: MuxNode<*, *, *>) {
+    override fun schedule(depth: Int, node: MuxNode<*, *, *>) {
         if (enqueued.putIfAbsent(node, node) == null) {
-            chan.send(Pair(depth, node))
+            scheduledQ.add(Pair(depth, node))
         }
     }
 
-    override suspend fun scheduleIndirect(indirectDepth: Int, node: MuxNode<*, *, *>) {
+    override fun scheduleIndirect(indirectDepth: Int, node: MuxNode<*, *, *>) {
         schedule(Int.MIN_VALUE + indirectDepth, node)
     }
 
-    suspend fun activate() {
-        for (nodeSchedule in chan) {
-            scheduledQ.add(nodeSchedule)
-            drainChan()
-        }
-    }
-
     internal suspend fun drainEval(network: Network) {
         drain { runStep ->
             runStep { muxNode -> network.evalScope { muxNode.visit(this) } }
             // If any visited MuxPromptNodes had their depths increased, eagerly propagate those
-            // depth
-            // changes now before performing further network evaluation.
+            // depth changes now before performing further network evaluation.
             network.compactor.drainCompact()
         }
     }
@@ -71,19 +61,12 @@
         crossinline onStep:
             suspend (runStep: suspend (visit: suspend (MuxNode<*, *, *>) -> Unit) -> Unit) -> Unit
     ): Unit = coroutineScope {
-        while (!chan.isEmpty || scheduledQ.isNotEmpty()) {
-            drainChan()
+        while (scheduledQ.isNotEmpty()) {
             val maxDepth = scheduledQ.peek()?.first ?: error("Unexpected empty scheduler")
             onStep { visit -> runStep(maxDepth, visit) }
         }
     }
 
-    private suspend fun drainChan() {
-        while (!chan.isEmpty) {
-            scheduledQ.add(chan.receive())
-        }
-    }
-
     private suspend inline fun runStep(
         maxDepth: Int,
         crossinline visit: suspend (MuxNode<*, *, *>) -> Unit,
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/TStateImpl.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/TStateImpl.kt
index 5cec05c..c68b4c3 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/TStateImpl.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/TStateImpl.kt
@@ -314,6 +314,28 @@
         @Suppress("UNCHECKED_CAST") transform(a as A, b as B, c as C, d as D)
     }
 
+internal fun <A, B, C, D, E, Z> zipStates(
+    name: String?,
+    operatorName: String,
+    l1: TStateImpl<A>,
+    l2: TStateImpl<B>,
+    l3: TStateImpl<C>,
+    l4: TStateImpl<D>,
+    l5: TStateImpl<E>,
+    transform: suspend EvalScope.(A, B, C, D, E) -> Z,
+): TStateImpl<Z> =
+    zipStates(null, operatorName, mapOf(0 to l1, 1 to l2, 2 to l3, 3 to l4, 4 to l5)).map(
+        name,
+        operatorName,
+    ) {
+        val a = it.getValue(0)
+        val b = it.getValue(1)
+        val c = it.getValue(2)
+        val d = it.getValue(3)
+        val e = it.getValue(4)
+        @Suppress("UNCHECKED_CAST") transform(a as A, b as B, c as C, d as D, e as E)
+    }
+
 internal fun <K : Any, A> zipStates(
     name: String?,
     operatorName: String,
diff --git a/packages/SystemUI/utils/kairos/test/com/android/systemui/kairos/KairosTests.kt b/packages/SystemUI/utils/kairos/test/com/android/systemui/kairos/KairosTests.kt
index 165230b..688adae 100644
--- a/packages/SystemUI/utils/kairos/test/com/android/systemui/kairos/KairosTests.kt
+++ b/packages/SystemUI/utils/kairos/test/com/android/systemui/kairos/KairosTests.kt
@@ -1170,12 +1170,12 @@
                                     mergeIncrementally
                                         .onEach { println("patch: $it") }
                                         .foldMapIncrementally()
-                                        .flatMap { it.combineValues() }
+                                        .flatMap { it.combine() }
                                 }
                             }
                         }
                         .foldMapIncrementally()
-                        .flatMap { it.combineValues() }
+                        .flatMap { it.combine() }
 
                 accState.toStateFlow()
             }
@@ -1300,6 +1300,26 @@
     }
 
     @Test
+    fun buildScope_stateAccumulation() = runFrpTest { network ->
+        val input = network.mutableTFlow<Unit>()
+        var observedCount: Int? = null
+        activateSpec(network) {
+            val (c, j) = asyncScope { input.fold(0) { _, x -> x + 1 } }
+            deferredBuildScopeAction { c.get().observe { observedCount = it } }
+        }
+        runCurrent()
+        assertEquals(0, observedCount)
+
+        input.emit(Unit)
+        runCurrent()
+        assertEquals(1, observedCount)
+
+        input.emit(Unit)
+        runCurrent()
+        assertEquals(2, observedCount)
+    }
+
+    @Test
     fun effect() = runFrpTest { network ->
         val input = network.mutableTFlow<Unit>()
         var effectRunning = false
diff --git a/packages/Vcn/flags/Android.bp b/packages/Vcn/flags/Android.bp
index 3943c6f..8d09fdb 100644
--- a/packages/Vcn/flags/Android.bp
+++ b/packages/Vcn/flags/Android.bp
@@ -29,10 +29,24 @@
     ],
 }
 
+// TODO: b/374174952 Remove this library when VCN modularization is done
 java_aconfig_library {
     name: "android.net.vcn.flags-aconfig-java-export",
     aconfig_declarations: "android.net.vcn.flags-aconfig",
     mode: "exported",
     min_sdk_version: "35",
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
+    apex_available: [
+        "//apex_available:platform",
+    ],
+}
+
+java_aconfig_library {
+    name: "android.net.vcn.flags-aconfig-java",
+    aconfig_declarations: "android.net.vcn.flags-aconfig",
+    min_sdk_version: "35",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+    apex_available: [
+        "com.android.tethering",
+    ],
 }
diff --git a/packages/Vcn/framework-b/Android.bp b/packages/Vcn/framework-b/Android.bp
index c312116..edb22c0 100644
--- a/packages/Vcn/framework-b/Android.bp
+++ b/packages/Vcn/framework-b/Android.bp
@@ -32,9 +32,9 @@
 }
 
 java_defaults {
-    name: "framework-connectivity-b-defaults",
+    name: "framework-connectivity-b-defaults-base",
     sdk_version: "module_current",
-    min_sdk_version: "35", // TODO: Make it Android 25Q2 when this is included in mainline
+
     defaults: ["framework-module-defaults"], // This is a boot jar
 
     srcs: [
@@ -44,14 +44,10 @@
 
     libs: [
         "android.net.ipsec.ike.stubs.module_lib",
-        "app-compat-annotations",
         "framework-wifi.stubs.module_lib",
         "unsupportedappusage",
     ],
-    static_libs: [
-        //TODO:375213246 Use a non-exported flag lib when VCN is in mainline
-        "android.net.vcn.flags-aconfig-java-export",
-    ],
+
     aidl: {
         include_dirs: [
             // For connectivity-framework classes such as Network.aidl, NetworkCapabilities.aidl
@@ -60,16 +56,83 @@
     },
 }
 
+soong_config_module_type {
+    name: "framework_connectivity_b_defaults_soong_config",
+    module_type: "java_defaults",
+    config_namespace: "ANDROID",
+    bool_variables: [
+        "is_vcn_in_mainline",
+    ],
+    properties: [
+        "min_sdk_version",
+        "static_libs",
+        "apex_available",
+    ],
+}
+
+framework_connectivity_b_defaults_soong_config {
+    name: "framework-connectivity-b-defaults",
+    defaults: [
+        "framework-connectivity-b-defaults-base",
+    ],
+    soong_config_variables: {
+        is_vcn_in_mainline: {
+            //TODO: b/380155299 Make it Baklava when aidl tool can understand it
+            min_sdk_version: "current",
+            static_libs: ["android.net.vcn.flags-aconfig-java"],
+            apex_available: ["com.android.tethering"],
+
+            conditions_default: {
+                min_sdk_version: "35",
+                static_libs: ["android.net.vcn.flags-aconfig-java-export"],
+                apex_available: ["//apex_available:platform"],
+            },
+        },
+    },
+}
+
+soong_config_module_type {
+    name: "framework_connectivity_b_java_sdk_library_defaults_soong_config",
+    module_type: "java_defaults",
+    config_namespace: "ANDROID",
+    bool_variables: [
+        "is_vcn_in_mainline",
+    ],
+    properties: [
+        "aconfig_declarations",
+        "jarjar_rules",
+    ],
+}
+
+framework_connectivity_b_java_sdk_library_defaults_soong_config {
+    name: "framework-connectivity-b-java-sdk-library-defaults",
+    soong_config_variables: {
+        is_vcn_in_mainline: {
+            aconfig_declarations: ["android.net.vcn.flags-aconfig-java"],
+
+            // TODO: b/375213246 Use the connectivity jarjar rule generator to create the
+            // jarjar rules. In the end state, use "framework-connectivity-jarjar-rules"
+            // after VCN code is moved to the Connectivity folder
+            jarjar_rules: "framework-vcn-jarjar-rules.txt",
+
+            conditions_default: {
+                aconfig_declarations: ["android.net.vcn.flags-aconfig-java-export"],
+
+                // Use "android.net.connectivity" as prefix would trigger
+                // "Hidden API flags are inconsistent" build error
+                jarjar_rules: "framework-vcn-jarjar-rules-platform.txt",
+            },
+        },
+    },
+}
+
 java_sdk_library {
     name: "framework-connectivity-b",
     defaults: [
         "framework-connectivity-b-defaults",
+        "framework-connectivity-b-java-sdk-library-defaults",
     ],
 
-    //TODO: b/375213246 Use "framework-connectivity-jarjar-rules" when VCN is
-    // in mainline
-    jarjar_rules: "framework-vcn-jarjar-rules.txt",
-
     permitted_packages: [
         "android.net",
         "android.net.vcn",
@@ -92,11 +155,6 @@
         "framework-connectivity-pre-jarjar",
     ],
 
-    aconfig_declarations: [
-        //TODO:375213246 Use a non-exported flag lib when VCN is in mainline
-        "android.net.vcn.flags-aconfig-java-export",
-    ],
-
     impl_library_visibility: [
         // Using for test only
         "//cts/tests/netlegacy22.api",
@@ -120,17 +178,13 @@
         "//packages/modules/Wifi/service/tests/wifitests",
     ],
 
-    apex_available: [
-        // TODO: b/374174952 Remove it when VCN modularization is released
-        "//apex_available:platform",
-
-        "com.android.tethering",
-    ],
+    visibility: ["//packages/modules/Connectivity:__subpackages__"],
 }
 
 java_library {
     name: "framework-connectivity-b-pre-jarjar",
     defaults: ["framework-connectivity-b-defaults"],
+    installable: false,
     libs: [
         "framework-connectivity-pre-jarjar",
     ],
diff --git a/packages/Vcn/framework-b/framework-vcn-jarjar-rules-platform.txt b/packages/Vcn/framework-b/framework-vcn-jarjar-rules-platform.txt
new file mode 100644
index 0000000..757043b
--- /dev/null
+++ b/packages/Vcn/framework-b/framework-vcn-jarjar-rules-platform.txt
@@ -0,0 +1,2 @@
+rule android.net.vcn.persistablebundleutils.** android.net.vcn.module.repackaged.persistablebundleutils.@1
+rule android.net.vcn.util.** android.net.vcn.module.repackaged.util.@1
\ No newline at end of file
diff --git a/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt b/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt
index 757043b..7e27b24 100644
--- a/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt
+++ b/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt
@@ -1,2 +1,2 @@
-rule android.net.vcn.persistablebundleutils.** android.net.vcn.module.repackaged.persistablebundleutils.@1
-rule android.net.vcn.util.** android.net.vcn.module.repackaged.util.@1
\ No newline at end of file
+rule android.net.vcn.persistablebundleutils.** android.net.connectivity.android.net.vcn.persistablebundleutils.@1
+rule android.net.vcn.util.** android.net.connectivity.android.net.vcn.util.@1
\ No newline at end of file
diff --git a/packages/Vcn/framework-b/src/android/net/ConnectivityFrameworkInitializerBaklava.java b/packages/Vcn/framework-b/src/android/net/ConnectivityFrameworkInitializerBaklava.java
index 1f0fa92..de22ca6 100644
--- a/packages/Vcn/framework-b/src/android/net/ConnectivityFrameworkInitializerBaklava.java
+++ b/packages/Vcn/framework-b/src/android/net/ConnectivityFrameworkInitializerBaklava.java
@@ -23,8 +23,6 @@
 import android.annotation.SystemApi;
 import android.app.SystemServiceRegistry;
 import android.compat.Compatibility;
-import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledSince;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.net.vcn.IVcnManagementService;
@@ -40,17 +38,15 @@
 @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API)
 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
 public final class ConnectivityFrameworkInitializerBaklava {
-    /**
-     * Starting with {@link VANILLA_ICE_CREAM}, Telephony feature flags (e.g. {@link
-     * PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}) are being checked before returning managers
-     * that depend on them. If the feature is missing, {@link Context#getSystemService} will return
-     * null.
-     *
-     * <p>This change is specific to VcnManager.
-     */
-    @ChangeId
-    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
-    private static final long ENABLE_CHECKING_TELEPHONY_FEATURES_FOR_VCN = 330902016;
+
+    // This is a copy of TelephonyFrameworkInitializer.ENABLE_CHECKING_TELEPHONY_FEATURES. This
+    // ChangeId will replace ENABLE_CHECKING_TELEPHONY_FEATURES_FOR_VCN to gate VcnManager
+    // feature flag enforcement.
+    // This replacement is safe because both ChangeIds have been enabled since Android V and serve
+    // the same purpose: enforcing telephony feature flag checks before using telephony-based
+    // features. This also simplifies VCN modularization by avoiding the need to handle different
+    // states, such as: SDK < B vs. SDK >= B; VCN in platform vs. VCN in the apex.
+    private static final long ENABLE_CHECKING_TELEPHONY_FEATURES = 330583731;
 
     /**
      * The corresponding vendor API for Android V
@@ -71,7 +67,7 @@
     private static String getVcnFeatureDependency() {
         // Check SDK version of the client app. Apps targeting pre-V SDK might
         // have not checked for existence of these features.
-        if (!Compatibility.isChangeEnabled(ENABLE_CHECKING_TELEPHONY_FEATURES_FOR_VCN)) {
+        if (!Compatibility.isChangeEnabled(ENABLE_CHECKING_TELEPHONY_FEATURES)) {
             return null;
         }
 
diff --git a/packages/Vcn/service-b/Android.bp b/packages/Vcn/service-b/Android.bp
index c1a1ee7..1370b06 100644
--- a/packages/Vcn/service-b/Android.bp
+++ b/packages/Vcn/service-b/Android.bp
@@ -32,11 +32,9 @@
     visibility: ["//frameworks/base/services/core"],
 }
 
-// Do not static include this lib in VCN because these files exist in
-// both service-connectivity.jar and framework.jar
-// TODO: b/374174952 After VCN moves to Connectivity/ and the modularization is done
-// this lib can be removed and "service-connectivity-b-pre-jarjar" can include
-// "service-connectivity-pre-jarjar"
+// TODO: b/374174952 This library is only used in "service-connectivity-b-platform"
+// After VCN moves to Connectivity/ and the modularization is done, this lib and
+// "service-connectivity-b-platform" can both be removed
 java_library {
     name: "connectivity-utils-service-vcn-internal",
     sdk_version: "module_current",
@@ -48,30 +46,30 @@
         "framework-annotations-lib",
         "unsupportedappusage",
     ],
-    visibility: [
-        "//visibility:private",
-    ],
-    apex_available: [
-        // TODO: b/374174952 Remove it when VCN modularization is released
-        "//apex_available:platform",
+    visibility: ["//visibility:private"],
+}
 
-        "com.android.tethering",
+filegroup {
+    name: "service-vcn-sources",
+    srcs: ["src/**/*.java"],
+    path: "src",
+    visibility: [
+        "//packages/modules/Connectivity/service-b",
     ],
 }
 
-java_library {
-    name: "service-connectivity-b-pre-jarjar",
-    sdk_version: "system_server_current",
-    min_sdk_version: "35", // TODO: Make it Android 25Q2 when this is included in mainline
+// This java_defaults will be used for "service-connectivity-b-platform" and
+// "service-connectivity-b-pre-jarjar"
+java_defaults {
+    name: "service-connectivity-b-pre-jarjar-defaults",
     defaults: ["framework-system-server-module-defaults"], // This is a system server jar
 
     srcs: [
-        "src/**/*.java",
+        ":service-vcn-sources",
     ],
 
     libs: [
         "android.net.ipsec.ike.stubs.module_lib",
-        "connectivity-utils-service-vcn-internal",
         "framework-annotations-lib",
         "framework-connectivity-pre-jarjar",
         "framework-connectivity-t-pre-jarjar",
@@ -89,13 +87,30 @@
         "modules-utils-handlerexecutor",
     ],
 
+    defaults_visibility: [
+        "//packages/modules/Connectivity/service-b",
+    ],
+}
+
+// This library is only used to be included into services.jar when the build system
+// flag RELEASE_MOVE_VCN_TO_MAINLINE is disabled. When the flag is enabled, a module
+// version of this library will be included in Tethering module
+java_library {
+    name: "service-connectivity-b-platform",
+    defaults: ["service-connectivity-b-pre-jarjar-defaults"],
+    static_libs: ["connectivity-utils-service-vcn-internal"],
+
+    sdk_version: "system_server_current",
+    min_sdk_version: "35",
+
+    // TODO (b/374174952 ): This file is for jarjaring files in
+    // "connectivity-utils-service-vcn-internal".
+    jarjar_rules: "service-vcn-platform-jarjar-rules.txt",
+
     visibility: [
         "//frameworks/base/services",
     ],
     apex_available: [
-        // TODO: b/374174952 Remove it when VCN modularization is released
         "//apex_available:platform",
-
-        "com.android.tethering",
     ],
 }
diff --git a/packages/Vcn/service-b/service-vcn-platform-jarjar-rules.txt b/packages/Vcn/service-b/service-vcn-platform-jarjar-rules.txt
new file mode 100644
index 0000000..3630727
--- /dev/null
+++ b/packages/Vcn/service-b/service-vcn-platform-jarjar-rules.txt
@@ -0,0 +1,5 @@
+rule android.util.IndentingPrintWriter android.net.vcn.module.repackaged.android.util.IndentingPrintWriter
+rule android.util.LocalLog android.net.vcn.module.repackaged.android.util.LocalLog
+rule com.android.internal.util.IndentingPrintWriter android.net.vcn.module.repackaged.com.android.internal.util.IndentingPrintWriter
+rule com.android.internal.util.MessageUtils android.net.vcn.module.repackaged.com.android.internal.util.MessageUtils
+rule com.android.internal.util.WakeupMessage android.net.vcn.module.repackaged.com.android.internal.util.WakeupMessage
\ No newline at end of file
diff --git a/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java b/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java
index 02c8ce4..81c7edf 100644
--- a/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java
+++ b/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java
@@ -16,7 +16,9 @@
 
 package com.android.server;
 
+import android.annotation.TargetApi;
 import android.content.Context;
+import android.os.Build;
 import android.util.Log;
 
 import com.android.tools.r8.keepanno.annotations.KeepItemKind;
@@ -30,6 +32,8 @@
 // Without this annotation, this class will be treated as unused class and be removed during build
 // time.
 @UsedByReflection(kind = KeepItemKind.CLASS_AND_METHODS)
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
 public final class ConnectivityServiceInitializerB extends SystemService {
     private static final String TAG = ConnectivityServiceInitializerB.class.getSimpleName();
     private final VcnManagementService mVcnManagementService;
diff --git a/packages/Vcn/service-b/src/com/android/server/VcnManagementService.java b/packages/Vcn/service-b/src/com/android/server/VcnManagementService.java
index 26db6a9..c9a99d7 100644
--- a/packages/Vcn/service-b/src/com/android/server/VcnManagementService.java
+++ b/packages/Vcn/service-b/src/com/android/server/VcnManagementService.java
@@ -37,6 +37,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
 import android.app.AppOpsManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -164,6 +165,8 @@
  * @hide
  */
 // TODO(b/180451994): ensure all incoming + outgoing calls have a cleared calling identity
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
 public class VcnManagementService extends IVcnManagementService.Stub {
     @NonNull private static final String TAG = VcnManagementService.class.getSimpleName();
     @NonNull private static final String CONTEXT_ATTRIBUTION_TAG = "VCN";
@@ -297,8 +300,10 @@
         });
     }
 
-    // Package-visibility for SystemServer to create instances.
-    static VcnManagementService create(@NonNull Context context) {
+    /** Called by ConnectivityServiceInitializerB to create instances. */
+    // VcnManagementService will be jarjared but ConnectivityServiceInitializerB will not. Thus this
+    // method needs to be public for ConnectivityServiceInitializerB to access
+    public static VcnManagementService create(@NonNull Context context) {
         return new VcnManagementService(context, new Dependencies());
     }
 
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/TelephonySubscriptionTracker.java b/packages/Vcn/service-b/src/com/android/server/vcn/TelephonySubscriptionTracker.java
index b448f75..b04e25d 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/TelephonySubscriptionTracker.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/TelephonySubscriptionTracker.java
@@ -22,12 +22,14 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TargetApi;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.vcn.VcnManager;
 import android.net.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
+import android.os.Build;
 import android.os.Handler;
 import android.os.ParcelUuid;
 import android.os.PersistableBundle;
@@ -77,6 +79,8 @@
  *
  * @hide
  */
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
 public class TelephonySubscriptionTracker extends BroadcastReceiver {
     @NonNull private static final String TAG = TelephonySubscriptionTracker.class.getSimpleName();
     private static final boolean LOG_DBG = false; // STOPSHIP if true
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java b/packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java
index 2524d0e..369ef6a 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java
@@ -29,6 +29,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TargetApi;
 import android.content.ContentResolver;
 import android.database.ContentObserver;
 import android.net.NetworkCapabilities;
@@ -39,6 +40,7 @@
 import android.net.vcn.VcnGatewayConnectionConfig;
 import android.net.vcn.VcnManager.VcnErrorCode;
 import android.net.vcn.util.LogUtils;
+import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
 import android.os.ParcelUuid;
@@ -75,6 +77,8 @@
  *
  * @hide
  */
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
 public class Vcn extends Handler {
     private static final String TAG = Vcn.class.getSimpleName();
 
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java b/packages/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java
index e50fc3a..300b80f 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java
@@ -37,6 +37,8 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
 import android.content.Context;
 import android.net.ConnectivityDiagnosticsManager;
 import android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback;
@@ -82,6 +84,7 @@
 import android.net.vcn.util.MtuUtils;
 import android.net.vcn.util.OneWayBoolean;
 import android.net.wifi.WifiInfo;
+import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
 import android.os.ParcelUuid;
@@ -171,6 +174,8 @@
  *
  * @hide
  */
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
 public class VcnGatewayConnection extends StateMachine {
     private static final String TAG = VcnGatewayConnection.class.getSimpleName();
 
@@ -2942,6 +2947,10 @@
          *
          * <p>Synchronize this action to minimize locking around WakeLock use.
          */
+        // WakelockTimeout suppressed because the time the wake lock is needed for is unknown. The
+        // wakelock is only acquired when a Message is sent to this state machine and will be
+        // released when the message is processed or the state machin quits
+        @SuppressLint("WakelockTimeout")
         public synchronized void acquire() {
             mImpl.acquire();
         }
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java b/packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java
index 4552f50..99c848f 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java
@@ -25,6 +25,7 @@
 import static com.android.server.VcnManagementService.VDBG;
 
 import android.annotation.NonNull;
+import android.annotation.TargetApi;
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.NetworkCapabilities;
@@ -32,6 +33,7 @@
 import android.net.NetworkRequest;
 import android.net.NetworkScore;
 import android.net.vcn.VcnGatewayConnectionConfig;
+import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
 import android.util.ArraySet;
@@ -54,6 +56,8 @@
  *
  * @hide
  */
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
 public class VcnNetworkProvider extends NetworkProvider {
     private static final String TAG = VcnNetworkProvider.class.getSimpleName();
 
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
index 72de613..6467af4 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
@@ -23,6 +23,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TargetApi;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -31,6 +32,7 @@
 import android.net.IpSecTransformState;
 import android.net.Network;
 import android.net.vcn.VcnManager;
+import android.os.Build;
 import android.os.Handler;
 import android.os.OutcomeReceiver;
 import android.os.PowerManager;
@@ -59,6 +61,8 @@
  *
  * <p>This class is flag gated by "network_metric_monitor" and "ipsec_tramsform_state"
  */
+// TODO(b/374174952) Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
 public class IpSecPacketLossDetector extends NetworkMetricMonitor {
     private static final String TAG = IpSecPacketLossDetector.class.getSimpleName();
 
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java
index 86cee55..1485344 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java
@@ -22,9 +22,11 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TargetApi;
 import android.net.IpSecTransform;
 import android.net.IpSecTransformState;
 import android.net.Network;
+import android.os.Build;
 import android.os.OutcomeReceiver;
 import android.util.CloseGuard;
 import android.util.Slog;
@@ -42,6 +44,8 @@
  *
  * <p>This class is flag gated by "network_metric_monitor"
  */
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
 public abstract class NetworkMetricMonitor implements AutoCloseable {
     private static final String TAG = NetworkMetricMonitor.class.getSimpleName();
 
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
index 79c4116..705141f 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
@@ -29,12 +29,14 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TargetApi;
 import android.net.NetworkCapabilities;
 import android.net.TelephonyNetworkSpecifier;
 import android.net.vcn.VcnCellUnderlyingNetworkTemplate;
 import android.net.vcn.VcnManager;
 import android.net.vcn.VcnUnderlyingNetworkTemplate;
 import android.net.vcn.VcnWifiUnderlyingNetworkTemplate;
+import android.os.Build;
 import android.os.ParcelUuid;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -50,6 +52,8 @@
 import java.util.Set;
 
 /** @hide */
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
 class NetworkPriorityClassifier {
     @NonNull private static final String TAG = NetworkPriorityClassifier.class.getSimpleName();
     /**
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
index 29a0762..bc552e7 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
@@ -28,6 +28,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TargetApi;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.IpSecTransform;
@@ -40,6 +41,7 @@
 import android.net.vcn.VcnGatewayConnectionConfig;
 import android.net.vcn.VcnUnderlyingNetworkTemplate;
 import android.net.vcn.util.LogUtils;
+import android.os.Build;
 import android.os.Handler;
 import android.os.ParcelUuid;
 import android.telephony.TelephonyCallback;
@@ -73,6 +75,8 @@
  *
  * @hide
  */
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
 public class UnderlyingNetworkController {
     @NonNull private static final String TAG = UnderlyingNetworkController.class.getSimpleName();
 
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java
index 30f4ed1..776931b 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java
@@ -22,12 +22,14 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TargetApi;
 import android.net.IpSecTransform;
 import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.vcn.VcnManager;
 import android.net.vcn.VcnUnderlyingNetworkTemplate;
+import android.os.Build;
 import android.os.Handler;
 import android.os.ParcelUuid;
 import android.util.IndentingPrintWriter;
@@ -50,6 +52,8 @@
  *
  * @hide
  */
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
 public class UnderlyingNetworkEvaluator {
     private static final String TAG = UnderlyingNetworkEvaluator.class.getSimpleName();
 
diff --git a/ravenwood/scripts/extract-last-soong-commands.py b/ravenwood/scripts/extract-last-soong-commands.py
index bdc1de0..c08d4aa 100755
--- a/ravenwood/scripts/extract-last-soong-commands.py
+++ b/ravenwood/scripts/extract-last-soong-commands.py
@@ -48,6 +48,7 @@
     with open(outfile, "w") as out:
         out.write(HEADER)
 
+        count = 0
         with gzip.open(log) as f:
             for line in f:
                 s = line.decode("utf-8")
@@ -63,7 +64,8 @@
                 if m:
                     command = m.groups()[0]
 
-                    out.write('#========\n')
+                    count += 1
+                    out.write(f'### Command {count} ========\n')
 
                     # Show the full command line before executing it.
                     out.write('#echo ' + shlex.quote(command) + '\n')
diff --git a/services/Android.bp b/services/Android.bp
index a7cb9bb..473911f 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -312,9 +312,11 @@
         "services.wifi",
         "service-blobstore",
         "service-jobscheduler",
-        "service-connectivity-b-pre-jarjar", // Move it to mainline module
         "android.hidl.base-V1.0-java",
-    ],
+    ] + select(release_flag("RELEASE_MOVE_VCN_TO_MAINLINE"), {
+        true: [],
+        default: ["service-connectivity-b-platform"],
+    }),
 
     libs: [
         "android.hidl.manager-V1.0-java",
diff --git a/services/appfunctions/Android.bp b/services/appfunctions/Android.bp
index eb6e468..7337aa2 100644
--- a/services/appfunctions/Android.bp
+++ b/services/appfunctions/Android.bp
@@ -19,6 +19,7 @@
     defaults: ["platform_service_defaults"],
     srcs: [
         ":services.appfunctions-sources",
+        ":statslog-appfunctions-java-gen",
         "java/**/*.logtags",
     ],
     libs: ["services.core"],
@@ -26,3 +27,10 @@
         baseline_filename: "lint-baseline.xml",
     },
 }
+
+genrule {
+    name: "statslog-appfunctions-java-gen",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --java $(out) --module appfunctions --javaPackage com.android.server.appfunctions --javaClass AppFunctionsStatsLog --minApiLevel 35",
+    out: ["java/com/android/server/appfunctions/AppFunctionsStatsLog.java"],
+}
diff --git a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionExecutors.java b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionExecutors.java
index 81e83b5..eaea443 100644
--- a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionExecutors.java
+++ b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionExecutors.java
@@ -16,6 +16,8 @@
 
 package com.android.server.appfunctions;
 
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
@@ -35,6 +37,11 @@
                     /* workQueue= */ new LinkedBlockingQueue<>(),
                     new NamedThreadFactory("AppFunctionExecutors"));
 
+    /** Executor for stats logging. */
+    public static final ExecutorService LOGGING_THREAD_EXECUTOR =
+            Executors.newSingleThreadExecutor(
+                    new NamedThreadFactory("AppFunctionsLoggingExecutors"));
+
     static {
         THREAD_POOL_EXECUTOR.allowCoreThreadTimeOut(true);
     }
diff --git a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java
index c17c340..669025f 100644
--- a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java
+++ b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java
@@ -30,6 +30,7 @@
 import android.app.appfunctions.AppFunctionRuntimeMetadata;
 import android.app.appfunctions.AppFunctionStaticMetadataHelper;
 import android.app.appfunctions.ExecuteAppFunctionAidlRequest;
+import android.app.appfunctions.ExecuteAppFunctionResponse;
 import android.app.appfunctions.IAppFunctionEnabledCallback;
 import android.app.appfunctions.IAppFunctionManager;
 import android.app.appfunctions.IAppFunctionService;
@@ -85,6 +86,7 @@
     private final ServiceConfig mServiceConfig;
     private final Context mContext;
     private final Map<String, Object> mLocks = new WeakHashMap<>();
+    private final AppFunctionsLoggerWrapper mLoggerWrapper;
 
     public AppFunctionManagerServiceImpl(@NonNull Context context) {
         this(
@@ -93,7 +95,8 @@
                         context, IAppFunctionService.Stub::asInterface, THREAD_POOL_EXECUTOR),
                 new CallerValidatorImpl(context),
                 new ServiceHelperImpl(context),
-                new ServiceConfigImpl());
+                new ServiceConfigImpl(),
+                new AppFunctionsLoggerWrapper(context));
     }
 
     @VisibleForTesting
@@ -102,12 +105,14 @@
             RemoteServiceCaller<IAppFunctionService> remoteServiceCaller,
             CallerValidator callerValidator,
             ServiceHelper appFunctionInternalServiceHelper,
-            ServiceConfig serviceConfig) {
+            ServiceConfig serviceConfig,
+            AppFunctionsLoggerWrapper loggerWrapper) {
         mContext = Objects.requireNonNull(context);
         mRemoteServiceCaller = Objects.requireNonNull(remoteServiceCaller);
         mCallerValidator = Objects.requireNonNull(callerValidator);
         mInternalServiceHelper = Objects.requireNonNull(appFunctionInternalServiceHelper);
         mServiceConfig = serviceConfig;
+        mLoggerWrapper = loggerWrapper;
     }
 
     /** Called when the user is unlocked. */
@@ -146,8 +151,27 @@
         Objects.requireNonNull(requestInternal);
         Objects.requireNonNull(executeAppFunctionCallback);
 
+        int callingUid = Binder.getCallingUid();
+        int callingPid = Binder.getCallingPid();
+
         final SafeOneTimeExecuteAppFunctionCallback safeExecuteAppFunctionCallback =
-                new SafeOneTimeExecuteAppFunctionCallback(executeAppFunctionCallback);
+                new SafeOneTimeExecuteAppFunctionCallback(executeAppFunctionCallback,
+                        new SafeOneTimeExecuteAppFunctionCallback.CompletionCallback() {
+                            @Override
+                            public void finalizeOnSuccess(
+                                    @NonNull ExecuteAppFunctionResponse result,
+                                    long executionStartTimeMillis) {
+                                mLoggerWrapper.logAppFunctionSuccess(requestInternal, result,
+                                        callingUid, executionStartTimeMillis);
+                            }
+
+                            @Override
+                            public void finalizeOnError(@NonNull AppFunctionException error,
+                                    long executionStartTimeMillis) {
+                                mLoggerWrapper.logAppFunctionError(requestInternal,
+                                        error.getErrorCode(), callingUid, executionStartTimeMillis);
+                            }
+                        });
 
         String validatedCallingPackage;
         try {
@@ -162,9 +186,6 @@
             return null;
         }
 
-        int callingUid = Binder.getCallingUid();
-        int callingPid = Binder.getCallingPid();
-
         ICancellationSignal localCancelTransport = CancellationSignal.createTransport();
 
         THREAD_POOL_EXECUTOR.execute(
diff --git a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionsLoggerWrapper.java b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionsLoggerWrapper.java
new file mode 100644
index 0000000..7ba1bbc
--- /dev/null
+++ b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionsLoggerWrapper.java
@@ -0,0 +1,83 @@
+/*
+ * 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.appfunctions;
+
+import static com.android.server.appfunctions.AppFunctionExecutors.LOGGING_THREAD_EXECUTOR;
+
+import android.annotation.NonNull;
+import android.app.appfunctions.ExecuteAppFunctionAidlRequest;
+import android.app.appfunctions.ExecuteAppFunctionResponse;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.SystemClock;
+import android.util.Slog;
+
+import java.util.Objects;
+
+/** Wraps AppFunctionsStatsLog. */
+public class AppFunctionsLoggerWrapper {
+    private static final String TAG = AppFunctionsLoggerWrapper.class.getSimpleName();
+
+    private static final int SUCCESS_RESPONSE_CODE = -1;
+
+    private final Context mContext;
+
+    public AppFunctionsLoggerWrapper(@NonNull Context context) {
+        mContext = Objects.requireNonNull(context);
+    }
+
+    void logAppFunctionSuccess(ExecuteAppFunctionAidlRequest request,
+            ExecuteAppFunctionResponse response, int callingUid, long executionStartTimeMillis) {
+        logAppFunctionsRequestReported(request, SUCCESS_RESPONSE_CODE,
+                response.getResponseDataSize(), callingUid, executionStartTimeMillis);
+    }
+
+    void logAppFunctionError(ExecuteAppFunctionAidlRequest request, int errorCode, int callingUid,
+            long executionStartTimeMillis) {
+        logAppFunctionsRequestReported(request, errorCode, /* responseSizeBytes = */ 0, callingUid,
+                executionStartTimeMillis);
+    }
+
+    private void logAppFunctionsRequestReported(ExecuteAppFunctionAidlRequest request,
+            int errorCode, int responseSizeBytes, int callingUid, long executionStartTimeMillis) {
+        final long e2eRequestLatencyMillis =
+                SystemClock.elapsedRealtime() - request.getRequestTime();
+        final long requestOverheadMillis =
+                executionStartTimeMillis > 0 ? (executionStartTimeMillis - request.getRequestTime())
+                        : e2eRequestLatencyMillis;
+        LOGGING_THREAD_EXECUTOR.execute(() -> AppFunctionsStatsLog.write(
+                AppFunctionsStatsLog.APP_FUNCTIONS_REQUEST_REPORTED,
+                /* callerPackageUid= */ callingUid,
+                /* targetPackageUid= */
+                getPackageUid(request.getClientRequest().getTargetPackageName()),
+                /* errorCode= */ errorCode,
+                /* requestSizeBytes= */ request.getClientRequest().getRequestDataSize(),
+                /* responseSizeBytes= */  responseSizeBytes,
+                /* requestDurationMs= */ e2eRequestLatencyMillis,
+                /* requestOverheadMs= */ requestOverheadMillis)
+        );
+    }
+
+    private int getPackageUid(String packageName) {
+        try {
+            return mContext.getPackageManager().getPackageUid(packageName, 0);
+        } catch (PackageManager.NameNotFoundException e) {
+            Slog.e(TAG, "Package uid not found for " + packageName);
+        }
+        return 0;
+    }
+}
diff --git a/services/appfunctions/java/com/android/server/appfunctions/RunAppFunctionServiceCallback.java b/services/appfunctions/java/com/android/server/appfunctions/RunAppFunctionServiceCallback.java
index c689bb9..a5ae7e3 100644
--- a/services/appfunctions/java/com/android/server/appfunctions/RunAppFunctionServiceCallback.java
+++ b/services/appfunctions/java/com/android/server/appfunctions/RunAppFunctionServiceCallback.java
@@ -16,8 +16,8 @@
 package com.android.server.appfunctions;
 
 import android.annotation.NonNull;
-import android.app.appfunctions.ExecuteAppFunctionAidlRequest;
 import android.app.appfunctions.AppFunctionException;
+import android.app.appfunctions.ExecuteAppFunctionAidlRequest;
 import android.app.appfunctions.ExecuteAppFunctionResponse;
 import android.app.appfunctions.IAppFunctionService;
 import android.app.appfunctions.ICancellationCallback;
@@ -52,6 +52,7 @@
             @NonNull IAppFunctionService service,
             @NonNull ServiceUsageCompleteListener serviceUsageCompleteListener) {
         try {
+            mSafeExecuteAppFunctionCallback.setExecutionStartTimeMillis();
             service.executeAppFunction(
                     mRequestInternal.getClientRequest(),
                     mRequestInternal.getCallingPackage(),
diff --git a/services/autofill/bugfixes.aconfig b/services/autofill/bugfixes.aconfig
index 5e1b147..65c446e 100644
--- a/services/autofill/bugfixes.aconfig
+++ b/services/autofill/bugfixes.aconfig
@@ -9,6 +9,16 @@
 }
 
 flag {
+  name: "improve_fill_dialog_aconfig"
+  namespace: "autofill"
+  description: "Improvements for Fill Dialog. Guard DeviceConfig rollout "
+  bug: "382493181"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
   name: "fill_fields_from_current_session_only"
   namespace: "autofill"
   description: "Only fill autofill fields that are part of the current session."
@@ -76,3 +86,23 @@
   description: "Highlight single field after autofill selection"
   bug: "41496744"
 }
+
+flag {
+  name: "metrics_fixes"
+  namespace: "autofill"
+  description: "Fixes various framework reported metrics"
+  bug: "362581326, 363011343"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
+  name: "add_accessibility_title_for_augmented_autofill_dropdown"
+  namespace: "autofill"
+  description: "Add accessibility title for augmented autofill dropdown"
+  bug: "375284244"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java b/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java
index 219b788..5e7e557 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java
@@ -354,6 +354,13 @@
         }
     }
 
+    private void handleOnInputMethodStartInputView() {
+        synchronized (mLock) {
+            mUiCallback.onInputMethodStartInputView();
+            handleOnReceiveImeStatusUpdated(true, true);
+        }
+    }
+
     /**
      * Handles the IME session status received from the IME.
      *
@@ -437,8 +444,8 @@
             final AutofillInlineSuggestionsRequestSession session = mSession.get();
             if (session != null) {
                 session.mHandler.sendMessage(obtainMessage(
-                        AutofillInlineSuggestionsRequestSession::handleOnReceiveImeStatusUpdated,
-                        session, true, true));
+                        AutofillInlineSuggestionsRequestSession::handleOnInputMethodStartInputView,
+                        session));
             }
         }
 
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 259ea14..cba8c66 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -2139,6 +2139,32 @@
         }
 
         @Override
+        public void notifyImeAnimationStart(int sessionId, long startTimeMs, int userId) {
+            synchronized (mLock) {
+                final AutofillManagerServiceImpl service =
+                        peekServiceForUserWithLocalBinderIdentityLocked(userId);
+                if (service != null) {
+                    service.notifyImeAnimationStart(sessionId, startTimeMs, getCallingUid());
+                } else if (sVerbose) {
+                    Slog.v(TAG, "notifyImeAnimationStart(): no service for " + userId);
+                }
+            }
+        }
+
+        @Override
+        public void notifyImeAnimationEnd(int sessionId, long endTimeMs, int userId) {
+            synchronized (mLock) {
+                final AutofillManagerServiceImpl service =
+                        peekServiceForUserWithLocalBinderIdentityLocked(userId);
+                if (service != null) {
+                    service.notifyImeAnimationEnd(sessionId, endTimeMs, getCallingUid());
+                } else if (sVerbose) {
+                    Slog.v(TAG, "notifyImeAnimationEnd(): no service for " + userId);
+                }
+            }
+        }
+
+        @Override
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
 
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 5cf96bf..0fa43ac 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -823,6 +823,36 @@
     }
 
     @GuardedBy("mLock")
+    public void notifyImeAnimationStart(int sessionId, long startTimeMs, int uid) {
+        if (!isEnabledLocked()) {
+            Slog.wtf(TAG, "Service not enabled");
+            return;
+        }
+        final Session session = mSessions.get(sessionId);
+        if (session == null || uid != session.uid) {
+            Slog.v(TAG, "notifyImeAnimationStart(): no session for "
+                    + sessionId + "(" + uid + ")");
+            return;
+        }
+        session.notifyImeAnimationStart(startTimeMs);
+    }
+
+    @GuardedBy("mLock")
+    public void notifyImeAnimationEnd(int sessionId, long endTimeMs, int uid) {
+        if (!isEnabledLocked()) {
+            Slog.wtf(TAG, "Service not enabled");
+            return;
+        }
+        final Session session = mSessions.get(sessionId);
+        if (session == null || uid != session.uid) {
+            Slog.v(TAG, "notifyImeAnimationEnd(): no session for "
+                    + sessionId + "(" + uid + ")");
+            return;
+        }
+        session.notifyImeAnimationEnd(endTimeMs);
+    }
+
+    @GuardedBy("mLock")
     @Override // from PerUserSystemService
     protected void handlePackageUpdateLocked(@NonNull String packageName) {
         final ServiceInfo serviceInfo = mFieldClassificationStrategy.getServiceInfo();
diff --git a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
index bd1b0ea..6ccf5e4 100644
--- a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
+++ b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
@@ -45,6 +45,7 @@
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_NO_FOCUS;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_REQUEST_TIMEOUT;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SESSION_COMMITTED_PREMATURELY;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SUGGESTION_FILTER_OUT;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_UNKNOWN_REASON;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_CHANGED;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_FOCUSED_BEFORE_FILL_DIALOG_RESPONSE;
@@ -98,6 +99,7 @@
             NOT_SHOWN_REASON_REQUEST_FAILED,
             NOT_SHOWN_REASON_NO_FOCUS,
             NOT_SHOWN_REASON_SESSION_COMMITTED_PREMATURELY,
+            NOT_SHOWN_REASON_SUGGESTION_FILTERED,
             NOT_SHOWN_REASON_UNKNOWN
     })
     @Retention(RetentionPolicy.SOURCE)
@@ -178,6 +180,8 @@
             AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SESSION_COMMITTED_PREMATURELY;
     public static final int NOT_SHOWN_REASON_UNKNOWN =
             AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_UNKNOWN_REASON;
+    public static final int NOT_SHOWN_REASON_SUGGESTION_FILTERED =
+            AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SUGGESTION_FILTER_OUT;
 
     public static final int AUTHENTICATION_TYPE_UNKNOWN =
             AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_TYPE__AUTHENTICATION_TYPE_UNKNOWN;
@@ -286,12 +290,43 @@
         });
     }
 
+    /**
+     * Call this when first entering the View. It will check if there are pre-existing characters
+     * in the view, and sets NOT_SHOWN_REASON_SUGGESTION_FILTERED if there is
+     */
+    public void maybeSetNoPresentationEventReasonSuggestionsFiltered(AutofillValue value) {
+        mEventInternal.ifPresent(
+                event -> {
+                    if (value == null || !value.isText()) {
+                        return;
+                    }
+
+                    int length = value.getTextValue().length();
+
+                    if (length > 0) {
+                        maybeSetNoPresentationEventReason(NOT_SHOWN_REASON_SUGGESTION_FILTERED);
+                    }
+                });
+    }
+
     public void maybeSetNoPresentationEventReasonIfNoReasonExists(@NotShownReason int reason) {
-        mEventInternal.ifPresent(event -> {
-            if (event.mCountShown == 0 && event.mNoPresentationReason == NOT_SHOWN_REASON_UNKNOWN) {
-                event.mNoPresentationReason = reason;
-            }
-        });
+        mEventInternal.ifPresent(
+                event -> {
+                    if (event.mCountShown != 0) {
+                        return;
+                    }
+
+                    // The only events that can be overwritten.
+                    // NOT_SHOWN_REASON_UNKNOWN is the default for inline/dropdown
+                    // NOT_SHOWN_REASON_NO_FOCUS is the default for fill dialog
+                    if (event.mNoPresentationReason != NOT_SHOWN_REASON_UNKNOWN
+                            || event.mNoPresentationReason != NOT_SHOWN_REASON_NO_FOCUS) {
+                        Slog.d(TAG, "Not setting no presentation reason because it already exists");
+                        return;
+                    }
+
+                    event.mNoPresentationReason = reason;
+                });
     }
 
     public void maybeSetAvailableCount(@Nullable List<Dataset> datasetList,
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 6b227d7..ba9865d 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -40,6 +40,8 @@
 import static android.service.autofill.FillRequest.FLAG_VIEW_REQUESTS_CREDMAN_SERVICE;
 import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;
 import static android.service.autofill.Flags.highlightAutofillSingleField;
+import static android.service.autofill.Flags.improveFillDialogAconfig;
+import static android.service.autofill.Flags.metricsFixes;
 import static android.view.autofill.AutofillManager.ACTION_RESPONSE_EXPIRED;
 import static android.view.autofill.AutofillManager.ACTION_START_SESSION;
 import static android.view.autofill.AutofillManager.ACTION_VALUE_CHANGED;
@@ -50,6 +52,7 @@
 import static android.view.autofill.AutofillManager.EXTRA_AUTOFILL_REQUEST_ID;
 import static android.view.autofill.AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM;
 import static android.view.autofill.AutofillManager.getSmartSuggestionModeToString;
+
 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 import static com.android.server.autofill.FillRequestEventLogger.TRIGGER_REASON_EXPLICITLY_REQUESTED;
 import static com.android.server.autofill.FillRequestEventLogger.TRIGGER_REASON_NORMAL_TRIGGER;
@@ -184,6 +187,7 @@
 import android.view.autofill.IAutofillWindowPresenter;
 import android.view.inputmethod.InlineSuggestionsRequest;
 import android.widget.RemoteViews;
+
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.logging.MetricsLogger;
@@ -195,6 +199,7 @@
 import com.android.server.autofill.ui.PendingUi;
 import com.android.server.inputmethod.InputMethodManagerInternal;
 import com.android.server.wm.ActivityTaskManagerInternal;
+
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -248,6 +253,8 @@
     private static final int DEFAULT__FILL_REQUEST_ID_SNAPSHOT = -2;
     private static final int DEFAULT__FIELD_CLASSIFICATION_REQUEST_ID_SNAPSHOT = -2;
 
+    private static final long DEFAULT_UNASSIGNED_TIME = -1;
+
     static final String SESSION_ID_KEY = "autofill_session_id";
     static final String REQUEST_ID_KEY = "autofill_request_id";
 
@@ -292,6 +299,31 @@
     @Retention(RetentionPolicy.SOURCE)
     @interface SessionState {}
 
+    /**
+     * Indicates fill dialog will not be shown.
+     */
+    private static final int SHOW_FILL_DIALOG_NO = 0;
+
+    /**
+     * Indicates fill dialog is shown.
+     */
+    private static final int SHOW_FILL_DIALOG_YES = 1;
+
+    /**
+     * Indicates fill dialog can be shown, but we need to wait.
+     * For eg, if the IME animation is happening, we need for it to complete before fill dialog can
+     * be shown.
+     */
+    private static final int SHOW_FILL_DIALOG_WAIT = 2;
+
+    @IntDef(prefix = { "SHOW_FILL_DIALOG_" }, value = {
+            SHOW_FILL_DIALOG_NO,
+            SHOW_FILL_DIALOG_YES,
+            SHOW_FILL_DIALOG_WAIT
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    private @interface ShowFillDialogState{}
+
     @GuardedBy("mLock")
     private final SessionFlags mSessionFlags;
 
@@ -576,6 +608,47 @@
 
     private boolean mIgnoreViewStateResetToEmpty;
 
+    /**
+     * Whether improveFillDialog feature is enabled or not.
+     * Configured via device config flag and aconfig flag.
+     */
+    private final boolean mImproveFillDialogEnabled;
+
+    /**
+     * Timeout, after which, fill dialog won't be shown.
+     * Configured via device config flag.
+     */
+    private final long mFillDialogTimeoutMs;
+
+    /**
+     * Time to wait after ime Animation ends before showing up fill dialog.
+     * Configured via device config flag.
+     */
+    private final long mFillDialogMinWaitAfterImeAnimationMs;
+
+    /**
+     * Indicates the need to wait for ime animation to end before showing up fill dialog.
+     * This is set when we receive notification of ime animation start.
+     * Focussing on one input field from another wouldn't cause ime to re-animate. So this will let
+     * us know whether we need to wait for ime animation finish notification.
+     */
+    private boolean mWaitForImeAnimation;
+
+    /**
+     * A runnable set to run when there is a need to wait for ime animation to end before showing
+     * up fill dialog. This is set only if the fill response has been received, and the response
+     * is eligible for showing up fill dialog, but the ime animation hasn't completed. This allows
+     * for this runnable to be scheduled/run when the ime animation ends, in order to show fill
+     * dialog.
+     */
+    private Runnable mFillDialogRunnable;
+
+    private long mImeAnimationFinishTimeMs = DEFAULT_UNASSIGNED_TIME;
+
+    private long mImeAnimationStartTimeMs = DEFAULT_UNASSIGNED_TIME;
+
+    private long mLastInputStartTime = DEFAULT_UNASSIGNED_TIME;
+
     /*
      * Id of the previous view that was entered. Once set, it would only be replaced by non-null
      * view ids.
@@ -1493,6 +1566,12 @@
         // Now request the assist structure data.
         requestAssistStructureLocked(requestId, flags);
 
+        if (mImproveFillDialogEnabled) {
+            // New request has been sent, so re-enable fill dialog.
+            // Fill dialog is eligible to be shown after each Fill request.
+            enableFillDialog();
+        }
+
         return Optional.of(requestId);
     }
 
@@ -1657,6 +1736,11 @@
         mSaveEventLogger = SaveEventLogger.forSessionId(sessionId, mLatencyBaseTime);
         mIsPrimaryCredential = isPrimaryCredential;
         mIgnoreViewStateResetToEmpty = AutofillFeatureFlags.shouldIgnoreViewStateResetToEmpty();
+        mImproveFillDialogEnabled =
+                improveFillDialogAconfig() && AutofillFeatureFlags.isImproveFillDialogEnabled();
+        mFillDialogTimeoutMs = AutofillFeatureFlags.getFillDialogTimeoutMs();
+        mFillDialogMinWaitAfterImeAnimationMs =
+                AutofillFeatureFlags.getFillDialogMinWaitAfterImeAnimationtEndMs();
 
         synchronized (mLock) {
             mSessionFlags = new SessionFlags();
@@ -1682,6 +1766,13 @@
                             public void notifyInlineUiHidden(AutofillId autofillId) {
                                 notifyFillUiHidden(autofillId);
                             }
+
+                            @Override
+                            public void onInputMethodStartInputView() {
+                                // TODO(b/377868687): This method isn't called when IME doesn't
+                                //  support inline suggestion. Handle those cases as well.
+                                onInputMethodStart();
+                            }
                         });
 
         mMetricsLogger.write(
@@ -3044,6 +3135,12 @@
         }
     }
 
+    private void onInputMethodStart() {
+        synchronized (mLock) {
+            mLastInputStartTime = SystemClock.elapsedRealtime();
+        }
+    }
+
     private void doStartIntentSender(IntentSender intentSender, Intent intent) {
         try {
             synchronized (mLock) {
@@ -3645,8 +3742,13 @@
         final FillResponse lastResponse = getLastResponseLocked("logContextCommited(%s)");
         if (lastResponse == null) return;
 
-        mPresentationStatsEventLogger.maybeSetNoPresentationEventReason(
-                PresentationStatsEventLogger.getNoPresentationEventReason(commitReason));
+        if (metricsFixes()) {
+            mPresentationStatsEventLogger.maybeSetNoPresentationEventReasonIfNoReasonExists(
+                    PresentationStatsEventLogger.getNoPresentationEventReason(commitReason));
+        } else {
+            mPresentationStatsEventLogger.maybeSetNoPresentationEventReason(
+                    PresentationStatsEventLogger.getNoPresentationEventReason(commitReason));
+        }
         mPresentationStatsEventLogger.logAndEndEvent("Context committed");
 
         final int flags = lastResponse.getFlags();
@@ -5029,6 +5131,13 @@
                     mPreviouslyFillDialogPotentiallyStarted = false;
                 } else {
                     mPreviouslyFillDialogPotentiallyStarted = true;
+                    if (metricsFixes()) {
+                        // Set the default reason for now if the user doesn't trigger any focus
+                        // event on the autofillable view. This can be changed downstream when
+                        // more information is available or session is committed.
+                        mPresentationStatsEventLogger.maybeSetNoPresentationEventReason(
+                                NOT_SHOWN_REASON_NO_FOCUS);
+                    }
                 }
                 Optional<Integer> maybeRequestId =
                         requestNewFillResponseLocked(
@@ -5195,6 +5304,10 @@
                     if (maybeNewRequestId.isPresent()) {
                         mPresentationStatsEventLogger.maybeSetRequestId(maybeNewRequestId.get());
                     }
+                    if (metricsFixes()) {
+                        mPresentationStatsEventLogger
+                                .maybeSetNoPresentationEventReasonSuggestionsFiltered(value);
+                    }
                 }
 
                 logPresentationStatsOnViewEnteredLocked(
@@ -5229,8 +5342,14 @@
 
                     // It's not necessary that there's no more presentation for this view. It could
                     // be that the user chose some suggestion, in which case, view exits.
-                    mPresentationStatsEventLogger.maybeSetNoPresentationEventReason(
-                            NOT_SHOWN_REASON_VIEW_FOCUS_CHANGED);
+                    if (metricsFixes()) {
+                        mPresentationStatsEventLogger
+                                .maybeSetNoPresentationEventReasonIfNoReasonExists(
+                                        NOT_SHOWN_REASON_VIEW_FOCUS_CHANGED);
+                    } else {
+                        mPresentationStatsEventLogger.maybeSetNoPresentationEventReason(
+                                NOT_SHOWN_REASON_VIEW_FOCUS_CHANGED);
+                    }
                 }
                 break;
             default:
@@ -5407,6 +5526,15 @@
         }
     }
 
+    private void resetImeAnimationState() {
+        synchronized (mLock) {
+            mWaitForImeAnimation = false;
+            mImeAnimationStartTimeMs = DEFAULT_UNASSIGNED_TIME;
+            mImeAnimationFinishTimeMs = DEFAULT_UNASSIGNED_TIME;
+            mLastInputStartTime = DEFAULT_UNASSIGNED_TIME;
+        }
+    }
+
     @Override
     public void onFillReady(
             @NonNull FillResponse response,
@@ -5452,18 +5580,24 @@
 
         final AutofillId[] ids = response.getFillDialogTriggerIds();
         if (ids != null && ArrayUtils.contains(ids, filledId)) {
-            if (requestShowFillDialog(response, filledId, filterText, flags)) {
+            @ShowFillDialogState int fillDialogState =
+                    requestShowFillDialog(response, filledId, filterText, flags);
+            if (fillDialogState == SHOW_FILL_DIALOG_YES) {
                 synchronized (mLock) {
                     final ViewState currentView = mViewStates.get(mCurrentViewId);
                     currentView.setState(ViewState.STATE_FILL_DIALOG_SHOWN);
                 }
-                // Just show fill dialog once, so disabled after shown.
+                // Just show fill dialog once per fill request, so disabled after shown.
                 // Note: Cannot disable before requestShowFillDialog() because the method
-                //       need to check whether fill dialog enabled.
+                //       need to check whether fill dialog is enabled.
                 setFillDialogDisabled();
+                resetImeAnimationState();
                 return;
-            } else {
+            }  else if (fillDialogState == SHOW_FILL_DIALOG_NO) {
+                resetImeAnimationState();
                 setFillDialogDisabled();
+            } else { // SHOW_FILL_DIALOG_WAIT
+                return;
             }
         }
 
@@ -5559,7 +5693,20 @@
         }
     }
 
+    private void enableFillDialog() {
+        if (sVerbose) {
+            Slog.v(TAG, "Enabling Fill Dialog....");
+        }
+        synchronized (mLock) {
+            mSessionFlags.mFillDialogDisabled = false;
+        }
+        notifyClientFillDialogTriggerIds(null);
+    }
+
     private void setFillDialogDisabled() {
+        if (sVerbose) {
+            Slog.v(TAG, "Disabling Fill Dialog.");
+        }
         synchronized (mLock) {
             mSessionFlags.mFillDialogDisabled = true;
         }
@@ -5577,24 +5724,28 @@
         }
     }
 
-    private boolean requestShowFillDialog(
+    private @ShowFillDialogState int requestShowFillDialog(
             FillResponse response, AutofillId filledId, String filterText, int flags) {
         if (!isFillDialogUiEnabled()) {
+            // TODO(b/377868687): The above check includes credman fields. We may want to show
+            //  credman fields again.
             // Unsupported fill dialog UI
-            if (sDebug) Log.w(TAG, "requestShowFillDialog: fill dialog is disabled");
-            return false;
+            if (sDebug) Log.w(TAG, "requestShowFillDialog(): fill dialog is disabled");
+            return SHOW_FILL_DIALOG_NO;
         }
 
-        if ((flags & FillRequest.FLAG_IME_SHOWING) != 0) {
-            // IME is showing, fallback to normal suggestions UI
-            if (sDebug) Log.w(TAG, "requestShowFillDialog: IME is showing");
-            return false;
-        }
+        if (!mImproveFillDialogEnabled) {
+            if ((flags & FillRequest.FLAG_IME_SHOWING) != 0) {
+                // IME is showing, fallback to normal suggestions UI
+                if (sDebug) Log.w(TAG, "requestShowFillDialog(): IME is showing");
+                return SHOW_FILL_DIALOG_NO;
+            }
 
-        if (mInlineSessionController.isImeShowing()) {
-            // IME is showing, fallback to normal suggestions UI
-            // Note: only work when inline suggestions supported
-            return false;
+            if (mInlineSessionController.isImeShowing()) {
+                // IME is showing, fallback to normal suggestions UI
+                // Note: only work when inline suggestions supported
+                return SHOW_FILL_DIALOG_NO;
+            }
         }
 
         synchronized (mLock) {
@@ -5602,29 +5753,84 @@
                     || !ArrayUtils.contains(mLastFillDialogTriggerIds, filledId)) {
                 // Last fill dialog triggered ids are changed.
                 if (sDebug) Log.w(TAG, "Last fill dialog triggered ids are changed.");
-                return false;
+                return SHOW_FILL_DIALOG_NO;
+            }
+
+            if (mImproveFillDialogEnabled && mInlineSessionController.isImeShowing()) {
+                long currentTimestampMs = SystemClock.elapsedRealtime();
+                long durationMs = currentTimestampMs - mLastInputStartTime;
+                if (sVerbose) {
+                    Log.d(TAG, "IME is showing. Checking for elapsed time ");
+                    Log.d(TAG, "IME is showing. Timestamps start: " + mLastInputStartTime
+                            + " current: " +  currentTimestampMs + " duration: " + durationMs
+                            + " mFillDialogTimeoutMs: " + mFillDialogTimeoutMs);
+                }
+
+                // Following situations can arise wrt IME animation.
+                // 1. No animation happening (eg IME already animated). In that case,
+                // mWaitForImeAnimation should be false. This is possible if the IME is already up
+                // on a field, but the user focusses on another field. Under such condition,
+                // since IME has already animated, there won't be another animation. However,
+                // onInputStartInputView is still called.
+                // 2. Animation is still proceeding. We should wait for animation to finish,
+                // and then proceed.
+                // 3. Animation is complete.
+                if (mWaitForImeAnimation) {
+                    // we need to wait for animation to happen. We can't return from here yet.
+                    // This is the situation #2 described above.
+                    Log.d(TAG, "Waiting for ime animation to complete before showing fill dialog");
+                    mFillDialogRunnable = createFillDialogEvalRunnable(
+                            response, filledId, filterText, flags);
+                    return SHOW_FILL_DIALOG_WAIT;
+                }
+
+                // Incorporate situations 1 & 3 discussed above. We calculate the duration from the
+                // max of start input time or the ime finish time
+                long effectiveDuration = currentTimestampMs
+                        - Math.max(mLastInputStartTime, mImeAnimationFinishTimeMs);
+                if (effectiveDuration >= mFillDialogTimeoutMs) {
+                    Log.d(TAG, "Fill dialog not shown since IME has been up for more time than "
+                            + mFillDialogTimeoutMs + "ms");
+                    return SHOW_FILL_DIALOG_NO;
+                } else if (effectiveDuration < mFillDialogMinWaitAfterImeAnimationMs) {
+                    // we need to wait for some time after animation ends
+                    Runnable runnable = createFillDialogEvalRunnable(
+                            response, filledId, filterText, flags);
+                    mHandler.postDelayed(runnable,
+                            mFillDialogMinWaitAfterImeAnimationMs - effectiveDuration);
+                    return SHOW_FILL_DIALOG_WAIT;
+                }
             }
         }
 
+        showFillDialog(response, filledId, filterText);
+        return SHOW_FILL_DIALOG_YES;
+    }
+
+    private Runnable createFillDialogEvalRunnable(
+            @NonNull FillResponse response,
+            @NonNull AutofillId filledId,
+            String filterText,
+            int flags) {
+        return () -> {
+            synchronized (mLock) {
+                AutofillValue value = AutofillValue.forText(filterText);
+                onFillReady(response, filledId, value, flags);
+            }
+        };
+    }
+
+    private void showFillDialog(FillResponse response, AutofillId filledId, String filterText) {
         Drawable serviceIcon = null;
+        PresentationStatsEventLogger logger = null;
         synchronized (mLock) {
             serviceIcon = getServiceIcon(response);
+            logger = mPresentationStatsEventLogger;
         }
 
-        getUiForShowing()
-                .showFillDialog(
-                        filledId,
-                        response,
-                        filterText,
-                        mService.getServicePackageName(),
-                        mComponentName,
-                        serviceIcon,
-                        this,
-                        id,
-                        mCompatMode,
-                        mPresentationStatsEventLogger,
-                        mLock);
-        return true;
+        getUiForShowing().showFillDialog(filledId, response, filterText,
+                mService.getServicePackageName(), mComponentName, serviceIcon, this,
+                id, mCompatMode, logger, mLock);
     }
 
     /**
@@ -6752,11 +6958,15 @@
     private void startNewEventForPresentationStatsEventLogger() {
         synchronized (mLock) {
             mPresentationStatsEventLogger.startNewEvent();
-            // Set the default reason for now if the user doesn't trigger any focus event
-            // on the autofillable view. This can be changed downstream when more
-            // information is available or session is committed.
-            mPresentationStatsEventLogger.maybeSetNoPresentationEventReason(
-                    NOT_SHOWN_REASON_NO_FOCUS);
+            // This is a fill dialog only state, moved to when we set
+            // mPreviouslyFillDialogPotentiallyStarted = true
+            if (!metricsFixes()) {
+                // Set the default reason for now if the user doesn't trigger any focus event
+                // on the autofillable view. This can be changed downstream when more
+                // information is available or session is committed.
+                mPresentationStatsEventLogger.maybeSetNoPresentationEventReason(
+                        NOT_SHOWN_REASON_NO_FOCUS);
+            }
             mPresentationStatsEventLogger.maybeSetDetectionPreference(
                     getDetectionPreferenceForLogging());
             mPresentationStatsEventLogger.maybeSetAutofillServiceUid(getAutofillServiceUid());
@@ -7513,7 +7723,11 @@
         if (sVerbose) {
             Slog.v(TAG, "logAllEvents(" + id + "): commitReason: " + val);
         }
-        mSessionCommittedEventLogger.maybeSetCommitReason(val);
+        if (metricsFixes()) {
+            mSessionCommittedEventLogger.maybeSetCommitReasonIfUnset(val);
+        } else {
+            mSessionCommittedEventLogger.maybeSetCommitReason(val);
+        }
         mSessionCommittedEventLogger.maybeSetRequestCount(mRequestCount);
         mSessionCommittedEventLogger.maybeSetSessionDurationMillis(
                 SystemClock.elapsedRealtime() - mStartTime);
@@ -7689,6 +7903,30 @@
         mSessionState = STATE_REMOVED;
     }
 
+    @GuardedBy("mLock")
+    public void notifyImeAnimationStart(long startTimeMs) {
+        mImeAnimationStartTimeMs = startTimeMs;
+        mWaitForImeAnimation = true;
+    }
+
+    @GuardedBy("mLock")
+    public void notifyImeAnimationEnd(long endTimeMs) {
+        mImeAnimationFinishTimeMs = endTimeMs;
+        // Make sure to use mRunnable with synchronized
+        if (mFillDialogRunnable != null) {
+            if (sVerbose) {
+                Log.v(TAG, "Ime animation ended, starting fill dialog.");
+            }
+            mHandler.postDelayed(mFillDialogRunnable, mFillDialogMinWaitAfterImeAnimationMs);
+            mFillDialogRunnable = null;
+        } else {
+            if (sVerbose) {
+                Log.v(TAG, "Ime animation ended, no runnable present.");
+            }
+        }
+        mWaitForImeAnimation = false;
+    }
+
     void onPendingSaveUi(int operation, @NonNull IBinder token) {
         getUiForShowing().onPendingSaveUi(operation, token);
     }
diff --git a/services/autofill/java/com/android/server/autofill/SessionCommittedEventLogger.java b/services/autofill/java/com/android/server/autofill/SessionCommittedEventLogger.java
index 8f3c880..7fd5648 100644
--- a/services/autofill/java/com/android/server/autofill/SessionCommittedEventLogger.java
+++ b/services/autofill/java/com/android/server/autofill/SessionCommittedEventLogger.java
@@ -76,6 +76,17 @@
     });
   }
 
+  /** Set commit_reason if not already set */
+  public void maybeSetCommitReasonIfUnset(@AutofillCommitReason int val) {
+      mEventInternal.ifPresent(
+          event -> {
+            if (event.mCommitReason != COMMIT_REASON_UNKNOWN) {
+              return;
+            }
+            event.mCommitReason = val;
+          });
+  }
+
   /**
    * Set session_duration_millis as long as mEventInternal presents.
    */
diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java b/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java
index ffc80ee..7287bdd 100644
--- a/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java
@@ -409,5 +409,10 @@
          * Callback to notify inline ui is hidden.
          */
         void notifyInlineUiHidden(@NonNull AutofillId autofillId);
+
+        /**
+         * Callback to notify input method started.
+         */
+        void onInputMethodStartInputView();
     }
 }
diff --git a/services/companion/java/com/android/server/companion/utils/MetricUtils.java b/services/companion/java/com/android/server/companion/utils/MetricUtils.java
index 8ea5c89..83cbde6 100644
--- a/services/companion/java/com/android/server/companion/utils/MetricUtils.java
+++ b/services/companion/java/com/android/server/companion/utils/MetricUtils.java
@@ -21,6 +21,7 @@
 import static android.companion.AssociationRequest.DEVICE_PROFILE_COMPUTER;
 import static android.companion.AssociationRequest.DEVICE_PROFILE_GLASSES;
 import static android.companion.AssociationRequest.DEVICE_PROFILE_NEARBY_DEVICE_STREAMING;
+import static android.companion.AssociationRequest.DEVICE_PROFILE_SENSOR_DEVICE_STREAMING;
 import static android.companion.AssociationRequest.DEVICE_PROFILE_WATCH;
 
 import static com.android.internal.util.FrameworkStatsLog.CDM_ASSOCIATION_ACTION;
@@ -31,6 +32,7 @@
 import static com.android.internal.util.FrameworkStatsLog.CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_COMPUTER;
 import static com.android.internal.util.FrameworkStatsLog.CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_GLASSES;
 import static com.android.internal.util.FrameworkStatsLog.CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_NEARBY_DEVICE_STREAMING;
+import static com.android.internal.util.FrameworkStatsLog.CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_SENSOR_DEVICE_STREAMING;
 import static com.android.internal.util.FrameworkStatsLog.CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_NULL;
 import static com.android.internal.util.FrameworkStatsLog.CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_WATCH;
 import static com.android.internal.util.FrameworkStatsLog.write;
@@ -71,6 +73,10 @@
                 DEVICE_PROFILE_NEARBY_DEVICE_STREAMING,
                 CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_NEARBY_DEVICE_STREAMING
         );
+        map.put(
+                DEVICE_PROFILE_SENSOR_DEVICE_STREAMING,
+                CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_SENSOR_DEVICE_STREAMING
+        );
 
         METRIC_DEVICE_PROFILE = unmodifiableMap(map);
     }
diff --git a/services/companion/java/com/android/server/companion/utils/PermissionsUtils.java b/services/companion/java/com/android/server/companion/utils/PermissionsUtils.java
index f37e0c9..6431af5 100644
--- a/services/companion/java/com/android/server/companion/utils/PermissionsUtils.java
+++ b/services/companion/java/com/android/server/companion/utils/PermissionsUtils.java
@@ -28,6 +28,7 @@
 import static android.companion.AssociationRequest.DEVICE_PROFILE_COMPUTER;
 import static android.companion.AssociationRequest.DEVICE_PROFILE_GLASSES;
 import static android.companion.AssociationRequest.DEVICE_PROFILE_NEARBY_DEVICE_STREAMING;
+import static android.companion.AssociationRequest.DEVICE_PROFILE_SENSOR_DEVICE_STREAMING;
 import static android.companion.AssociationRequest.DEVICE_PROFILE_WATCH;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Binder.getCallingPid;
@@ -75,6 +76,8 @@
         map.put(DEVICE_PROFILE_GLASSES, Manifest.permission.REQUEST_COMPANION_PROFILE_GLASSES);
         map.put(DEVICE_PROFILE_NEARBY_DEVICE_STREAMING,
                 Manifest.permission.REQUEST_COMPANION_PROFILE_NEARBY_DEVICE_STREAMING);
+        map.put(DEVICE_PROFILE_SENSOR_DEVICE_STREAMING,
+                Manifest.permission.REQUEST_COMPANION_PROFILE_SENSOR_DEVICE_STREAMING);
 
         DEVICE_PROFILE_TO_PERMISSION = unmodifiableMap(map);
     }
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index 6729231d..1f3b316 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -103,7 +103,8 @@
     private static final List<String> VIRTUAL_DEVICE_COMPANION_DEVICE_PROFILES = Arrays.asList(
             AssociationRequest.DEVICE_PROFILE_AUTOMOTIVE_PROJECTION,
             AssociationRequest.DEVICE_PROFILE_APP_STREAMING,
-            AssociationRequest.DEVICE_PROFILE_NEARBY_DEVICE_STREAMING);
+            AssociationRequest.DEVICE_PROFILE_NEARBY_DEVICE_STREAMING,
+            AssociationRequest.DEVICE_PROFILE_SENSOR_DEVICE_STREAMING);
 
     /** Enable default device camera access for apps running on virtual devices. */
     @ChangeId
@@ -738,6 +739,11 @@
         public int getDevicePolicy(int deviceId, int policyType) {
             return mImpl.getDevicePolicy(deviceId, policyType);
         }
+
+        @Override // Binder call
+        public int getDeviceIdForDisplayId(int displayId) {
+            return mImpl.getDeviceIdForDisplayId(displayId);
+        }
     }
 
     private final class LocalService extends VirtualDeviceManagerInternal {
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 9e64559..06f9e2b 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -149,6 +149,9 @@
 
         // Java/AIDL sources to be moved out to CrashRecovery module
         ":services-crashrecovery-sources",
+
+        // Indicate whether VCN is in platform or mainline
+        ":vcn-location-sources",
     ],
 
     libs: [
@@ -160,7 +163,6 @@
         "android.hardware.vibrator-V3-java",
         "androidx.annotation_annotation",
         "app-compat-annotations",
-        "art_exported_aconfig_flags_lib",
         "framework-tethering.stubs.module_lib",
         "keepanno-annotations",
         "service-art.stubs.system_server",
@@ -223,7 +225,6 @@
         "securebox",
         "apache-commons-math",
         "battery_saver_flag_lib",
-        "guava",
         "notification_flags_lib",
         "power_hint_flags_lib",
         "biometrics_flags_lib",
@@ -247,6 +248,7 @@
         "locksettings_flags_lib",
         "profiling_flags_lib",
         "android.adpf.sessionmanager_aidl-java",
+        "uprobestats_flags_java_lib",
     ],
     javac_shard_size: 50,
     javacflags: [
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index 8da8358..96bdbb8 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -119,6 +119,10 @@
                     "include-filter": "android.os.storage.cts.StorageStatsManagerTest"
                 }
             ]
+        },
+        {
+            "name": "FrameworksMockingServicesTests_service_batteryServiceTest",
+            "file_patterns": ["BatteryService\\.java"]
         }
     ],
     "presubmit-large": [
@@ -176,10 +180,6 @@
                     "include-filter": "com.android.server.wm.BackgroundActivityStart*"
                 }
             ]
-        },
-        {
-            "name": "FrameworksMockingServicesTests_service_batteryServiceTest",
-            "file_patterns": ["BatteryService\\.java"]
         }
    ]
 }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index eba9a25..bd7a0ac 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -449,6 +449,8 @@
     private AtomicBoolean mIsSatelliteEnabled;
     private AtomicBoolean mWasSatelliteEnabledNotified;
 
+    private final int mPid = Process.myPid();
+
     /**
      * Per-phone map of precise data connection state. The key of the map is the pair of transport
      * type and APN setting. This is the cache to prevent redundant callbacks to the listeners.
@@ -1441,7 +1443,17 @@
                 }
                 if (events.contains(TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)) {
                     try {
-                        r.callback.onCallStatesChanged(mCallStateLists.get(r.phoneId));
+                        if (Flags.passCopiedCallStateList()) {
+                            List<CallState> callList;
+                            if (r.callerPid == mPid) {
+                                callList = List.copyOf(mCallStateLists.get(r.phoneId));
+                            } else {
+                                callList = mCallStateLists.get(r.phoneId);
+                            }
+                            r.callback.onCallStatesChanged(callList);
+                        } else {
+                            r.callback.onCallStatesChanged(mCallStateLists.get(r.phoneId));
+                        }
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
@@ -2573,12 +2585,25 @@
                 }
 
                 if (notifyCallState) {
+                    List<CallState> copyList = null;
                     for (Record r : mRecords) {
                         if (r.matchTelephonyCallbackEvent(
                                 TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)
                                 && idMatch(r, subId, phoneId)) {
+                            // If listener is in the same process, original instance can be passed
+                            // to the listener via AIDL without serialization/de-serialization. We
+                            // will pass the copied list. Since the element is newly created instead
+                            // of modification for the change, we can use shallow copy for this.
                             try {
-                                r.callback.onCallStatesChanged(mCallStateLists.get(phoneId));
+                                if (Flags.passCopiedCallStateList()) {
+                                    if (r.callerPid == mPid && copyList == null) {
+                                        copyList = List.copyOf(mCallStateLists.get(phoneId));
+                                    }
+                                    r.callback.onCallStatesChanged(copyList == null
+                                            ? mCallStateLists.get(phoneId) : copyList);
+                                } else {
+                                    r.callback.onCallStatesChanged(mCallStateLists.get(phoneId));
+                                }
                             } catch (RemoteException ex) {
                                 mRemoveList.add(r.binder);
                             }
@@ -2906,13 +2931,21 @@
                     log("There is no active call to report CallQuality");
                     return;
                 }
-
+                List<CallState> copyList = null;
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)
                             && idMatch(r, subId, phoneId)) {
                         try {
-                            r.callback.onCallStatesChanged(mCallStateLists.get(phoneId));
+                            if (Flags.passCopiedCallStateList()) {
+                                if (r.callerPid == mPid && copyList == null) {
+                                    copyList = List.copyOf(mCallStateLists.get(phoneId));
+                                }
+                                r.callback.onCallStatesChanged(copyList == null
+                                        ? mCallStateLists.get(phoneId) : copyList);
+                            } else {
+                                r.callback.onCallStatesChanged(mCallStateLists.get(phoneId));
+                            }
                         } catch (RemoteException ex) {
                             mRemoveList.add(r.binder);
                         }
diff --git a/services/core/java/com/android/server/am/BroadcastFilter.java b/services/core/java/com/android/server/am/BroadcastFilter.java
index 05aeb42..8327639 100644
--- a/services/core/java/com/android/server/am/BroadcastFilter.java
+++ b/services/core/java/com/android/server/am/BroadcastFilter.java
@@ -19,7 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledSince;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.os.Binder;
@@ -41,7 +40,6 @@
      * ({@link IntentFilter#SYSTEM_LOW_PRIORITY}, {@link IntentFilter#SYSTEM_HIGH_PRIORITY}).
      */
     @ChangeId
-    @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.BASE)
     @VisibleForTesting
     static final long RESTRICT_PRIORITY_VALUES = 371309185L;
 
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index a1ab1eea..8d0805d 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -43,7 +43,6 @@
 import android.app.BroadcastOptions;
 import android.app.BroadcastOptions.DeliveryGroupPolicy;
 import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledSince;
 import android.content.ComponentName;
 import android.content.IIntentReceiver;
 import android.content.Intent;
@@ -86,7 +85,6 @@
      * will only influence the order of broadcast delivery within the same process.
      */
     @ChangeId
-    @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.BASE)
     @VisibleForTesting
     static final long LIMIT_PRIORITY_SCOPE = 371307720L;
 
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 883e09f..87f87c7 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -143,6 +143,7 @@
         "tv_os",
         "aaos_carframework_triage",
         "aaos_performance_triage",
+        "aaos_input_triage",
         "aaos_user_triage",
         "aaos_window_triage",
         "aaos_audio_triage",
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 295e044..06c586f 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -3191,7 +3191,7 @@
                     resolveProxyPackageName, proxyAttributionTag, proxyVirtualDeviceId,
                     Process.INVALID_UID, null, null,
                     Context.DEVICE_ID_DEFAULT, proxyFlags, !isProxyTrusted,
-                    "proxy " + message, shouldCollectMessage, 1);
+                    "proxy " + message, shouldCollectMessage);
             if (proxyReturn.getOpMode() != AppOpsManager.MODE_ALLOWED) {
                 return new SyncNotedAppOp(proxyReturn.getOpMode(), code, proxiedAttributionTag,
                         proxiedPackageName);
@@ -3210,20 +3210,7 @@
         return noteOperationUnchecked(code, proxiedUid, resolveProxiedPackageName,
                 proxiedAttributionTag, proxiedVirtualDeviceId, proxyUid, resolveProxyPackageName,
                 proxyAttributionTag, proxyVirtualDeviceId, proxiedFlags, shouldCollectAsyncNotedOp,
-                message, shouldCollectMessage, 1);
-    }
-
-    @Override
-    public void noteOperationsInBatch(Map batchedNoteOps) {
-        for (var entry : ((Map<AppOpsManager.NotedOp, Integer>) batchedNoteOps).entrySet()) {
-            AppOpsManager.NotedOp notedOp = entry.getKey();
-            int notedCount = entry.getValue();
-            mCheckOpsDelegateDispatcher.noteOperation(
-                    notedOp.getOp(), notedOp.getUid(), notedOp.getPackageName(),
-                    notedOp.getAttributionTag(), notedOp.getVirtualDeviceId(),
-                    notedOp.getShouldCollectAsyncNotedOp(), notedOp.getMessage(),
-                    notedOp.getShouldCollectMessage(), notedCount);
-        }
+                message, shouldCollectMessage);
     }
 
     @Override
@@ -3241,7 +3228,7 @@
         }
         return mCheckOpsDelegateDispatcher.noteOperation(code, uid, packageName,
                 attributionTag, Context.DEVICE_ID_DEFAULT, shouldCollectAsyncNotedOp, message,
-                shouldCollectMessage, 1);
+                shouldCollectMessage);
     }
 
     @Override
@@ -3250,12 +3237,13 @@
             String message, boolean shouldCollectMessage) {
         return mCheckOpsDelegateDispatcher.noteOperation(code, uid, packageName,
                 attributionTag, virtualDeviceId, shouldCollectAsyncNotedOp, message,
-                shouldCollectMessage, 1);
+                shouldCollectMessage);
     }
 
     private SyncNotedAppOp noteOperationImpl(int code, int uid, @Nullable String packageName,
-            @Nullable String attributionTag, int virtualDeviceId, boolean shouldCollectAsyncNotedOp,
-            @Nullable String message, boolean shouldCollectMessage, int notedCount) {
+             @Nullable String attributionTag, int virtualDeviceId,
+             boolean shouldCollectAsyncNotedOp, @Nullable String message,
+             boolean shouldCollectMessage) {
         String resolvedPackageName;
         if (!shouldUseNewCheckOp()) {
             verifyIncomingUid(uid);
@@ -3290,14 +3278,14 @@
         return noteOperationUnchecked(code, uid, resolvedPackageName, attributionTag,
                 virtualDeviceId, Process.INVALID_UID, null, null,
                 Context.DEVICE_ID_DEFAULT, AppOpsManager.OP_FLAG_SELF, shouldCollectAsyncNotedOp,
-                message, shouldCollectMessage, notedCount);
+                message, shouldCollectMessage);
     }
 
     private SyncNotedAppOp noteOperationUnchecked(int code, int uid, @NonNull String packageName,
             @Nullable String attributionTag, int virtualDeviceId, int proxyUid,
             String proxyPackageName, @Nullable String proxyAttributionTag, int proxyVirtualDeviceId,
             @OpFlags int flags, boolean shouldCollectAsyncNotedOp, @Nullable String message,
-            boolean shouldCollectMessage, int notedCount) {
+            boolean shouldCollectMessage) {
         PackageVerificationResult pvr;
         try {
             pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName);
@@ -3400,11 +3388,11 @@
                     virtualDeviceId, flags, AppOpsManager.MODE_ALLOWED);
 
             attributedOp.accessed(proxyUid, proxyPackageName, proxyAttributionTag,
-                    getPersistentId(proxyVirtualDeviceId), uidState.getState(), flags, notedCount);
+                    getPersistentId(proxyVirtualDeviceId), uidState.getState(), flags);
 
             if (shouldCollectAsyncNotedOp) {
                 collectAsyncNotedOp(uid, packageName, code, attributionTag, flags, message,
-                        shouldCollectMessage, notedCount);
+                        shouldCollectMessage);
             }
 
             return new SyncNotedAppOp(AppOpsManager.MODE_ALLOWED, code, attributionTag,
@@ -3563,7 +3551,7 @@
      */
     private void collectAsyncNotedOp(int uid, @NonNull String packageName, int opCode,
             @Nullable String attributionTag, @OpFlags int flags, @NonNull String message,
-            boolean shouldCollectMessage, int notedCount) {
+            boolean shouldCollectMessage) {
         Objects.requireNonNull(message);
 
         int callingUid = Binder.getCallingUid();
@@ -3571,51 +3559,42 @@
         final long token = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
+                Pair<String, Integer> key = getAsyncNotedOpsKey(packageName, uid);
+
+                RemoteCallbackList<IAppOpsAsyncNotedCallback> callbacks = mAsyncOpWatchers.get(key);
+                AsyncNotedAppOp asyncNotedOp = new AsyncNotedAppOp(opCode, callingUid,
+                        attributionTag, message, System.currentTimeMillis());
+                final boolean[] wasNoteForwarded = {false};
+
                 if ((flags & (OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXIED)) != 0
                         && shouldCollectMessage) {
                     reportRuntimeAppOpAccessMessageAsyncLocked(uid, packageName, opCode,
                             attributionTag, message);
                 }
 
-                Pair<String, Integer> key = getAsyncNotedOpsKey(packageName, uid);
-                RemoteCallbackList<IAppOpsAsyncNotedCallback> callbacks = mAsyncOpWatchers.get(key);
-                if (callbacks == null) {
-                    return;
-                }
-
-                final boolean[] wasNoteForwarded = {false};
-                if (Flags.rateLimitBatchedNoteOpAsyncCallbacksEnabled()) {
-                    notedCount = 1;
-                }
-
-                for (int i = 0; i < notedCount; i++) {
-                    AsyncNotedAppOp asyncNotedOp = new AsyncNotedAppOp(opCode, callingUid,
-                            attributionTag, message, System.currentTimeMillis());
-                    wasNoteForwarded[0] = false;
+                if (callbacks != null) {
                     callbacks.broadcast((cb) -> {
                         try {
                             cb.opNoted(asyncNotedOp);
                             wasNoteForwarded[0] = true;
                         } catch (RemoteException e) {
                             Slog.e(TAG,
-                                    "Could not forward noteOp of " + opCode + " to "
-                                            + packageName
+                                    "Could not forward noteOp of " + opCode + " to " + packageName
                                             + "/" + uid + "(" + attributionTag + ")", e);
                         }
                     });
+                }
 
-                    if (!wasNoteForwarded[0]) {
-                        ArrayList<AsyncNotedAppOp> unforwardedOps = mUnforwardedAsyncNotedOps.get(
-                                key);
-                        if (unforwardedOps == null) {
-                            unforwardedOps = new ArrayList<>(1);
-                            mUnforwardedAsyncNotedOps.put(key, unforwardedOps);
-                        }
+                if (!wasNoteForwarded[0]) {
+                    ArrayList<AsyncNotedAppOp> unforwardedOps = mUnforwardedAsyncNotedOps.get(key);
+                    if (unforwardedOps == null) {
+                        unforwardedOps = new ArrayList<>(1);
+                        mUnforwardedAsyncNotedOps.put(key, unforwardedOps);
+                    }
 
-                        unforwardedOps.add(asyncNotedOp);
-                        if (unforwardedOps.size() > MAX_UNFORWARDED_OPS) {
-                            unforwardedOps.remove(0);
-                        }
+                    unforwardedOps.add(asyncNotedOp);
+                    if (unforwardedOps.size() > MAX_UNFORWARDED_OPS) {
+                        unforwardedOps.remove(0);
                     }
                 }
             }
@@ -4047,7 +4026,7 @@
 
         if (shouldCollectAsyncNotedOp && !isRestricted) {
             collectAsyncNotedOp(uid, packageName, code, attributionTag, AppOpsManager.OP_FLAG_SELF,
-                    message, shouldCollectMessage, 1);
+                    message, shouldCollectMessage);
         }
 
         return new SyncNotedAppOp(isRestricted ? MODE_IGNORED : MODE_ALLOWED, code, attributionTag,
@@ -7595,36 +7574,34 @@
 
         public SyncNotedAppOp noteOperation(int code, int uid, String packageName,
                 String attributionTag, int virtualDeviceId, boolean shouldCollectAsyncNotedOp,
-                String message, boolean shouldCollectMessage, int notedCount) {
+                String message, boolean shouldCollectMessage) {
             if (mPolicy != null) {
                 if (mCheckOpsDelegate != null) {
                     return mPolicy.noteOperation(code, uid, packageName, attributionTag,
                             virtualDeviceId, shouldCollectAsyncNotedOp, message,
-                            shouldCollectMessage, notedCount, this::noteDelegateOperationImpl
+                            shouldCollectMessage, this::noteDelegateOperationImpl
                     );
                 } else {
                     return mPolicy.noteOperation(code, uid, packageName, attributionTag,
                             virtualDeviceId, shouldCollectAsyncNotedOp, message,
-                            shouldCollectMessage, notedCount, AppOpsService.this::noteOperationImpl
+                            shouldCollectMessage, AppOpsService.this::noteOperationImpl
                     );
                 }
             } else if (mCheckOpsDelegate != null) {
                 return noteDelegateOperationImpl(code, uid, packageName, attributionTag,
-                        virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
-                        notedCount);
+                        virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage);
             }
             return noteOperationImpl(code, uid, packageName, attributionTag,
-                    virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
-                    notedCount);
+                    virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage);
         }
 
         private SyncNotedAppOp noteDelegateOperationImpl(int code, int uid,
                 @Nullable String packageName, @Nullable String featureId, int virtualDeviceId,
                 boolean shouldCollectAsyncNotedOp, @Nullable String message,
-                boolean shouldCollectMessage, int notedCount) {
+                boolean shouldCollectMessage) {
             return mCheckOpsDelegate.noteOperation(code, uid, packageName, featureId,
                     virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
-                    notedCount, AppOpsService.this::noteOperationImpl
+                    AppOpsService.this::noteOperationImpl
             );
         }
 
diff --git a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
index fa2e674..ca9a25b 100644
--- a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
+++ b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
@@ -28,6 +28,7 @@
 import static android.app.AppOpsManager.MODE_FOREGROUND;
 import static android.app.AppOpsManager.MODE_IGNORED;
 import static android.app.AppOpsManager.OP_CAMERA;
+import static android.app.AppOpsManager.OP_CONTROL_AUDIO;
 import static android.app.AppOpsManager.OP_NONE;
 import static android.app.AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO;
 import static android.app.AppOpsManager.OP_RECORD_AUDIO;
@@ -176,6 +177,8 @@
             case OP_RECORD_AUDIO:
             case OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO:
                 return PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
+            case OP_CONTROL_AUDIO:
+                return PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL;
             default:
                 return PROCESS_CAPABILITY_NONE;
         }
diff --git a/services/core/java/com/android/server/appop/AttributedOp.java b/services/core/java/com/android/server/appop/AttributedOp.java
index 4d114b4..314664b 100644
--- a/services/core/java/com/android/server/appop/AttributedOp.java
+++ b/services/core/java/com/android/server/appop/AttributedOp.java
@@ -100,12 +100,10 @@
      * @param proxyDeviceId       The device Id of the proxy
      * @param uidState            UID state of the app noteOp/startOp was called for
      * @param flags               OpFlags of the call
-     * @param accessCount         The number of times the op is accessed
      */
     public void accessed(int proxyUid, @Nullable String proxyPackageName,
             @Nullable String proxyAttributionTag, @Nullable String proxyDeviceId,
-            @AppOpsManager.UidState int uidState, @AppOpsManager.OpFlags int flags,
-            int accessCount) {
+            @AppOpsManager.UidState int uidState, @AppOpsManager.OpFlags int flags) {
         long accessTime = System.currentTimeMillis();
         accessed(accessTime, -1, proxyUid, proxyPackageName, proxyAttributionTag, proxyDeviceId,
                 uidState, flags);
@@ -113,7 +111,7 @@
         mAppOpsService.mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid,
                 parent.packageName, persistentDeviceId, tag, uidState, flags, accessTime,
                 AppOpsManager.ATTRIBUTION_FLAGS_NONE, AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE,
-                DiscreteRegistry.ACCESS_TYPE_NOTE_OP, accessCount);
+                DiscreteRegistry.ACCESS_TYPE_NOTE_OP);
     }
 
     /**
@@ -257,7 +255,7 @@
         if (isStarted) {
             mAppOpsService.mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid,
                     parent.packageName, persistentDeviceId, tag, uidState, flags, startTime,
-                    attributionFlags, attributionChainId, DiscreteRegistry.ACCESS_TYPE_START_OP, 1);
+                    attributionFlags, attributionChainId, DiscreteRegistry.ACCESS_TYPE_START_OP);
         }
     }
 
@@ -453,7 +451,7 @@
             mAppOpsService.mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid,
                     parent.packageName, persistentDeviceId, tag, event.getUidState(),
                     event.getFlags(), startTime, event.getAttributionFlags(),
-                    event.getAttributionChainId(), DiscreteRegistry.ACCESS_TYPE_RESUME_OP, 1);
+                    event.getAttributionChainId(), DiscreteRegistry.ACCESS_TYPE_RESUME_OP);
             if (shouldSendActive) {
                 mAppOpsService.scheduleOpActiveChangedIfNeededLocked(parent.op, parent.uid,
                         parent.packageName, tag, event.getVirtualDeviceId(), true,
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index 5e67f26..6b02538 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -475,7 +475,7 @@
             @NonNull String deviceId, @Nullable String attributionTag, @UidState int uidState,
             @OpFlags int flags, long accessTime,
             @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId,
-            @DiscreteRegistry.AccessType int accessType, int accessCount) {
+            @DiscreteRegistry.AccessType int accessType) {
         synchronized (mInMemoryLock) {
             if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
                 if (!isPersistenceInitializedMLocked()) {
@@ -484,7 +484,7 @@
                 }
                 getUpdatedPendingHistoricalOpsMLocked(
                         System.currentTimeMillis()).increaseAccessCount(op, uid, packageName,
-                        attributionTag, uidState, flags, accessCount);
+                        attributionTag, uidState, flags, 1);
 
                 mDiscreteRegistry.recordDiscreteAccess(uid, packageName, deviceId, op,
                         attributionTag, flags, uidState, accessTime, -1, attributionFlags,
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 34d4fb0..acb46d9 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -793,6 +793,7 @@
      * (see AudioService.onAudioServerDied() method)
      */
     // Always executed on AudioDeviceBroker message queue
+    @GuardedBy("mDeviceBroker.mDeviceStateLock")
     /*package*/ void onRestoreDevices() {
         synchronized (mDevicesLock) {
             int res;
@@ -815,6 +816,9 @@
                             "Device inventory restore failed to reconnect " + di,
                             EventLogger.Event.ALOGE, TAG);
                     mConnectedDevices.remove(di.getKey(), di);
+                    if (AudioSystem.isBluetoothScoDevice(di.mDeviceType)) {
+                        mDeviceBroker.onSetBtScoActiveDevice(null);
+                    }
                 }
             }
             mAppliedStrategyRolesInt.clear();
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 5928f81..1799b77 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -4177,6 +4177,12 @@
         // Stream mute changed, fire the intent.
         Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
         intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, isMuted);
+        if (replaceStreamBtSco() && isStreamBluetoothSco(streamType)) {
+            intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
+                    AudioSystem.STREAM_BLUETOOTH_SCO);
+            // in this case broadcast for both sco and voice_call streams the mute status
+            sendBroadcastToAll(intent, null /* options */);
+        }
         intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType);
         sendBroadcastToAll(intent, null /* options */);
     }
@@ -4684,6 +4690,12 @@
         switch (mode) {
             case AudioSystem.MODE_IN_COMMUNICATION:
             case AudioSystem.MODE_IN_CALL:
+                // TODO(b/382704431): remove to allow STREAM_VOICE_CALL to drive abs volume
+                //  over A2DP
+                if (getDeviceForStream(AudioSystem.STREAM_VOICE_CALL)
+                        == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
+                    return AudioSystem.STREAM_MUSIC;
+                }
                 return AudioSystem.STREAM_VOICE_CALL;
             case AudioSystem.MODE_CALL_SCREENING:
             case AudioSystem.MODE_COMMUNICATION_REDIRECT:
@@ -4695,15 +4707,20 @@
                 // other conditions will influence the stream type choice, read on...
                 break;
         }
-        if (voiceActivityCanOverride
-                && mVoicePlaybackActive.get()) {
+
+        if (voiceActivityCanOverride && mVoicePlaybackActive.get()) {
+            // TODO(b/382704431): remove to allow STREAM_VOICE_CALL to drive abs volume over A2DP
+            if (getDeviceForStream(AudioSystem.STREAM_VOICE_CALL)
+                    == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
+                return AudioSystem.STREAM_MUSIC;
+            }
             return AudioSystem.STREAM_VOICE_CALL;
         }
         return AudioSystem.STREAM_MUSIC;
     }
 
-    private AtomicBoolean mVoicePlaybackActive = new AtomicBoolean(false);
-    private AtomicBoolean mMediaPlaybackActive = new AtomicBoolean(false);
+    private final AtomicBoolean mVoicePlaybackActive = new AtomicBoolean(false);
+    private final AtomicBoolean mMediaPlaybackActive = new AtomicBoolean(false);
 
     private final IPlaybackConfigDispatcher mPlaybackActivityMonitor =
             new IPlaybackConfigDispatcher.Stub() {
@@ -4923,7 +4940,7 @@
     private void onUpdateContextualVolumes() {
         final int streamType = getBluetoothContextualVolumeStream();
 
-        Log.i(TAG,
+        Slog.i(TAG,
                 "onUpdateContextualVolumes: absolute volume driving streams " + streamType
                 + " avrcp supported: " + mAvrcpAbsVolSupported);
         synchronized (mCachedAbsVolDrivingStreamsLock) {
@@ -4932,7 +4949,7 @@
                 if (absDev == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
                     enabled = mAvrcpAbsVolSupported;
                     if (!enabled) {
-                        Log.w(TAG, "Updating avrcp not supported in onUpdateContextualVolumes");
+                        Slog.w(TAG, "Updating avrcp not supported in onUpdateContextualVolumes");
                     }
                 }
                 if (stream != streamType) {
@@ -4960,7 +4977,7 @@
             return;
         }
         if (absVolumeDevices.size() > 1) {
-            Log.w(TAG, "onUpdateContextualVolumes too many active devices: "
+            Slog.w(TAG, "onUpdateContextualVolumes too many active devices: "
                     + absVolumeDevices.stream().map(AudioSystem::getOutputDeviceName)
                         .collect(Collectors.joining(","))
                     + ", for stream: " + streamType);
@@ -4971,7 +4988,7 @@
         final int index = getStreamVolume(streamType, device);
 
         if (DEBUG_VOL) {
-            Log.i(TAG, "onUpdateContextualVolumes streamType: " + streamType
+            Slog.i(TAG, "onUpdateContextualVolumes streamType: " + streamType
                     + ", device: " + AudioSystem.getOutputDeviceName(device)
                     + ", index: " + index);
         }
@@ -9659,9 +9676,16 @@
                         mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
                         mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE,
                                 oldIndex);
-
-                        mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
-                                mStreamType);
+                        int extraStreamType = mStreamType;
+                        // TODO: remove this when deprecating STREAM_BLUETOOTH_SCO
+                        if (isStreamBluetoothSco(mStreamType)) {
+                            mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
+                                    AudioSystem.STREAM_BLUETOOTH_SCO);
+                            extraStreamType = AudioSystem.STREAM_BLUETOOTH_SCO;
+                        } else {
+                            mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
+                                    mStreamType);
+                        }
                         mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
                                 streamAlias);
 
@@ -9672,9 +9696,21 @@
                                         " aliased streams: " + aliasStreamIndexes;
                             }
                             AudioService.sVolumeLogger.enqueue(new VolChangedBroadcastEvent(
-                                    mStreamType, aliasStreamIndexesString, index, oldIndex));
+                                    extraStreamType, aliasStreamIndexesString, index, oldIndex));
+                            if (extraStreamType != mStreamType) {
+                                AudioService.sVolumeLogger.enqueue(new VolChangedBroadcastEvent(
+                                        mStreamType, aliasStreamIndexesString, index, oldIndex));
+                            }
                         }
                         sendBroadcastToAll(mVolumeChanged, mVolumeChangedOptions);
+                        if (extraStreamType != mStreamType) {
+                            // send multiple intents in case we merged voice call and bt sco streams
+                            mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
+                                    mStreamType);
+                            // do not use the options in thid case which could discard
+                            // the previous intent
+                            sendBroadcastToAll(mVolumeChanged, null);
+                        }
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
index 2513443..5d9db65 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
@@ -19,17 +19,19 @@
 import static android.Manifest.permission.CONTROL_DEVICE_STATE;
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED;
-import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN;
-import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN;
 import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FEATURE_DUAL_DISPLAY;
 import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FEATURE_REAR_DISPLAY;
 import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY;
 import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY;
+import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED;
+import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN;
+import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN;
 import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT;
 import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT;
 import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY;
 import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED;
 import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST;
 import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS;
 import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP;
@@ -98,7 +100,6 @@
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.WeakHashMap;
@@ -854,7 +855,7 @@
         }
     }
 
-    private void requestStateInternal(int state, int flags, int callingPid, int callingUid,
+    private void requestStateInternal(int requestedState, int flags, int callingPid, int callingUid,
             @NonNull IBinder token, boolean hasControlDeviceStatePermission) {
         synchronized (mLock) {
             final ProcessRecord processRecord = mProcessRecords.get(callingPid);
@@ -869,19 +870,30 @@
                         + " token: " + token);
             }
 
-            final Optional<DeviceState> deviceState = getStateLocked(state);
-            if (!deviceState.isPresent()) {
-                throw new IllegalArgumentException("Requested state: " + state
+            final Optional<DeviceState> requestedDeviceState = getStateLocked(requestedState);
+            if (requestedDeviceState.isEmpty()) {
+                throw new IllegalArgumentException("Requested state: " + requestedState
                         + " is not supported.");
             }
 
-            OverrideRequest request = new OverrideRequest(token, callingPid, callingUid,
-                    deviceState.get(), flags, OVERRIDE_REQUEST_TYPE_EMULATED_STATE);
+            final OverrideRequest request = new OverrideRequest(token, callingPid, callingUid,
+                    requestedDeviceState.get(), flags, OVERRIDE_REQUEST_TYPE_EMULATED_STATE);
 
             if (Flags.deviceStatePropertyMigration()) {
-                // If we don't have the CONTROL_DEVICE_STATE permission, we want to show the overlay
-                if (!hasControlDeviceStatePermission && deviceState.get().hasProperty(
-                        PROPERTY_FEATURE_REAR_DISPLAY)) {
+                final boolean isRequestingRdm = requestedDeviceState.get()
+                        .hasProperty(PROPERTY_FEATURE_REAR_DISPLAY);
+                final boolean isRequestingRdmOuterDefault = requestedDeviceState.get()
+                        .hasProperty(PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT);
+
+                final boolean isDeviceClosed = mCommittedState.isEmpty() ? false
+                        : mCommittedState.get().hasProperty(
+                                PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED);
+
+                final boolean shouldShowRdmEduDialog = isRequestingRdm && shouldShowRdmEduDialog(
+                        hasControlDeviceStatePermission, isRequestingRdmOuterDefault,
+                        isDeviceClosed);
+
+                if (shouldShowRdmEduDialog) {
                     showRearDisplayEducationalOverlayLocked(request);
                 } else {
                     mOverrideRequestController.addRequest(request);
@@ -889,7 +901,7 @@
             } else {
                 // If we don't have the CONTROL_DEVICE_STATE permission, we want to show the overlay
                 if (!hasControlDeviceStatePermission && mRearDisplayState != null
-                        && state == mRearDisplayState.getIdentifier()) {
+                        && requestedState == mRearDisplayState.getIdentifier()) {
                     showRearDisplayEducationalOverlayLocked(request);
                 } else {
                     mOverrideRequestController.addRequest(request);
@@ -899,6 +911,28 @@
     }
 
     /**
+     * Determines if the system should show an educational dialog before entering rear display mode
+     * @param hasControlDeviceStatePermission If the app has the CONTROL_DEVICE_STATE permission, we
+     *                                        don't need to show the overlay
+     * @param requestingRdmOuterDefault True if the system is requesting
+     *                                  PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT
+     * @param isDeviceClosed True if the device is closed (folded) when the request was made
+     */
+    @VisibleForTesting
+    static boolean shouldShowRdmEduDialog(boolean hasControlDeviceStatePermission,
+            boolean requestingRdmOuterDefault, boolean isDeviceClosed) {
+        if (hasControlDeviceStatePermission) {
+            return false;
+        }
+
+        if (requestingRdmOuterDefault) {
+            return isDeviceClosed;
+        } else {
+            return true;
+        }
+    }
+
+    /**
      * If we get a request to enter rear display  mode, we need to display an educational
      * overlay to let the user know what will happen. This calls into the
      * {@link StatusBarManagerInternal} to notify SystemUI to display the educational dialog.
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 452dc5f..0b633bd 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -2042,7 +2042,7 @@
                         // handles stopping the projection.
                         Slog.w(TAG, "Content Recording: failed to start mirroring - "
                                 + "releasing virtual display " + displayId);
-                        releaseVirtualDisplayInternal(callback.asBinder(), callingUid);
+                        releaseVirtualDisplayInternal(callback.asBinder());
                         return Display.INVALID_DISPLAY;
                     } else if (projection != null) {
                         // Indicate that this projection has been used to record, and can't be used
@@ -2131,7 +2131,7 @@
         // Something weird happened and the logical display was not created.
         Slog.w(TAG, "Rejecting request to create virtual display "
                 + "because the logical display was not created.");
-        mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder(), callingUid);
+        mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder());
         mDisplayDeviceRepo.onDisplayDeviceEvent(device,
                 DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED);
         return -1;
@@ -2158,14 +2158,14 @@
         }
     }
 
-    private void releaseVirtualDisplayInternal(IBinder appToken, int callingUid) {
+    private void releaseVirtualDisplayInternal(IBinder appToken) {
         synchronized (mSyncRoot) {
             if (mVirtualDisplayAdapter == null) {
                 return;
             }
 
             DisplayDevice device =
-                    mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken, callingUid);
+                    mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
             Slog.d(TAG, "Virtual Display: Display Device released");
             if (device != null) {
                 // TODO: multi-display - handle virtual displays the same as other display adapters.
@@ -4789,10 +4789,9 @@
 
         @Override // Binder call
         public void releaseVirtualDisplay(IVirtualDisplayCallback callback) {
-            final int callingUid = Binder.getCallingUid();
             final long token = Binder.clearCallingIdentity();
             try {
-                releaseVirtualDisplayInternal(callback.asBinder(), callingUid);
+                releaseVirtualDisplayInternal(callback.asBinder());
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 945365d..f48fbea 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -906,6 +906,11 @@
                 mLogicalDisplay.getPowerThrottlingDataIdLocked();
 
         mHandler.postAtTime(() -> {
+            if (mStopped) {
+                // DPC has already stopped, don't execute any more.
+                return;
+            }
+
             boolean changed = false;
 
             if (mIsEnabled != isEnabled || mIsInTransition != isInTransition) {
@@ -3306,7 +3311,7 @@
                 int displayId, SensorManager sensorManager) {
             return new DisplayPowerProximityStateController(wakelockController, displayDeviceConfig,
                     looper, nudgeUpdatePowerState,
-                    displayId, sensorManager, /* injector= */ null);
+                    displayId, sensorManager);
         }
 
         AutomaticBrightnessController getAutomaticBrightnessController(
diff --git a/services/core/java/com/android/server/display/DisplayPowerProximityStateController.java b/services/core/java/com/android/server/display/DisplayPowerProximityStateController.java
index 215932c..35455c8 100644
--- a/services/core/java/com/android/server/display/DisplayPowerProximityStateController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerProximityStateController.java
@@ -16,6 +16,8 @@
 
 package com.android.server.display;
 
+import android.annotation.IntDef;
+import android.annotation.Nullable;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
@@ -34,6 +36,8 @@
 import com.android.server.display.utils.SensorUtils;
 
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * Maintains the proximity state of the display.
@@ -42,18 +46,26 @@
  */
 public final class DisplayPowerProximityStateController {
     @VisibleForTesting
-    static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 1;
-    @VisibleForTesting
     static final int PROXIMITY_UNKNOWN = -1;
+    private static final int PROXIMITY_NEGATIVE = 0;
     @VisibleForTesting
     static final int PROXIMITY_POSITIVE = 1;
+
+    @IntDef(prefix = { "PROXIMITY_" }, value = {
+            PROXIMITY_UNKNOWN,
+            PROXIMITY_NEGATIVE,
+            PROXIMITY_POSITIVE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface ProximityState {}
+
+    @VisibleForTesting
+    static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 1;
     @VisibleForTesting
     static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
 
     private static final int MSG_IGNORE_PROXIMITY = 2;
 
-    private static final int PROXIMITY_NEGATIVE = 0;
-
     private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
     // Proximity sensor debounce delay in milliseconds for positive transitions.
 
@@ -73,7 +85,7 @@
     private final DisplayPowerProximityStateHandler mHandler;
     // A runnable to execute the utility to update the power state.
     private final Runnable mNudgeUpdatePowerState;
-    private Clock mClock;
+    private final Clock mClock;
     // A listener which listen's to the events emitted by the proximity sensor.
     private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
         @Override
@@ -117,9 +129,6 @@
     // with the sensor manager.
     private boolean mProximitySensorEnabled;
 
-    // The raw non-debounced proximity sensor state.
-    private int mPendingProximity = PROXIMITY_UNKNOWN;
-
     // -1 if fully debounced. Else, represents the time in ms when the debounce suspend blocker will
     // be removed. Applies for both positive and negative proximity flips.
     private long mPendingProximityDebounceTime = -1;
@@ -128,8 +137,11 @@
     // When the screen turns on again, we report user activity to the power manager.
     private boolean mScreenOffBecauseOfProximity;
 
+    // The raw non-debounced proximity sensor state.
+    private @ProximityState int mPendingProximity = PROXIMITY_UNKNOWN;
+
     // The debounced proximity sensor state.
-    private int mProximity = PROXIMITY_UNKNOWN;
+    private @ProximityState int mProximity = PROXIMITY_UNKNOWN;
 
     // The actual proximity sensor threshold value.
     private float mProximityThreshold;
@@ -139,7 +151,7 @@
     private boolean mSkipRampBecauseOfProximityChangeToNegative = false;
 
     // The DisplayId of the associated Logical Display.
-    private int mDisplayId;
+    private final int mDisplayId;
 
     /**
      * Create a new instance of DisplayPowerProximityStateController.
@@ -152,11 +164,18 @@
      * @param displayId             The DisplayId of the associated Logical Display.
      * @param sensorManager         The manager which lets us access the display's ProximitySensor
      */
-    public DisplayPowerProximityStateController(
-            WakelockController wakeLockController, DisplayDeviceConfig displayDeviceConfig,
-            Looper looper,
+    public DisplayPowerProximityStateController(WakelockController wakeLockController,
+            DisplayDeviceConfig displayDeviceConfig, Looper looper,
+            Runnable nudgeUpdatePowerState, int displayId, SensorManager sensorManager) {
+        this(wakeLockController, displayDeviceConfig, looper, nudgeUpdatePowerState, displayId,
+                sensorManager, new Injector());
+    }
+
+    @VisibleForTesting
+    DisplayPowerProximityStateController(WakelockController wakeLockController,
+            DisplayDeviceConfig displayDeviceConfig, Looper looper,
             Runnable nudgeUpdatePowerState, int displayId, SensorManager sensorManager,
-            Injector injector) {
+            @Nullable Injector injector) {
         if (injector == null) {
             injector = new Injector();
         }
@@ -437,7 +456,7 @@
                 if (mProximity != mPendingProximity) {
                     // if the status of the sensor changed, stop ignoring.
                     mIgnoreProximityUntilChanged = false;
-                    Slog.i(mTag, "No longer ignoring proximity [" + mPendingProximity + "]");
+                    Slog.i(mTag, "Applying proximity: " + proximityToString(mPendingProximity));
                 }
                 // Sensor reading accepted.  Apply the change then release the wake lock.
                 mProximity = mPendingProximity;
@@ -478,7 +497,7 @@
         }
     }
 
-    private String proximityToString(int state) {
+    private String proximityToString(@ProximityState int state) {
         switch (state) {
             case PROXIMITY_UNKNOWN:
                 return "Unknown";
@@ -518,12 +537,12 @@
     }
 
     @VisibleForTesting
-    int getPendingProximity() {
+    @ProximityState int getPendingProximity() {
         return mPendingProximity;
     }
 
     @VisibleForTesting
-    int getProximity() {
+    @ProximityState int getProximity() {
         return mProximity;
     }
 
@@ -550,7 +569,7 @@
     @VisibleForTesting
     static class Injector {
         Clock createClock() {
-            return () -> SystemClock.uptimeMillis();
+            return SystemClock::uptimeMillis;
         }
     }
 }
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index c0903a9..79592a65 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -506,9 +506,6 @@
             return;
         }
 
-        Slog.i(TAG, "Requesting Transition to state: " + state.getIdentifier() + ", from state="
-                + mDeviceState.getIdentifier() + ", interactive=" + mInteractive
-                + ", mBootCompleted=" + mBootCompleted);
         // As part of a state transition, we may need to turn off some displays temporarily so that
         // the transition is smooth. Plus, on some devices, only one internal displays can be
         // on at a time. We use LogicalDisplay.setIsInTransition to mark a display that needs to be
@@ -522,6 +519,11 @@
         final boolean sleepDevice = shouldDeviceBePutToSleep(mPendingDeviceState, mDeviceState,
                 mInteractive, mBootCompleted);
 
+        Slog.i(TAG, "Requesting Transition to state: " + state.getIdentifier() + ", from state="
+                + mDeviceState.getIdentifier() + ", interactive=" + mInteractive
+                + ", mBootCompleted=" + mBootCompleted + ", wakeDevice=" + wakeDevice
+                + ", sleepDevice=" + sleepDevice);
+
         // If all displays are off already, we can just transition here, unless we are trying to
         // wake or sleep the device as part of this transition. In that case defer the final
         // transition until later once the device is awake/asleep.
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 836f4ed..f14e452 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -91,6 +91,13 @@
 
     private final ArrayMap<IBinder, VirtualDisplayDevice> mVirtualDisplayDevices = new ArrayMap<>();
 
+    // When a virtual display is created, the mapping (appToken -> ownerUid) is stored here. That
+    // way, when the display is released later, we can retrieve the ownerUid and decrement
+    // the number of virtual displays that exist for that ownerUid. We can't use
+    // Binder.getCallingUid() because the display might be released by the system process and not
+    // the process that created the display.
+    private final ArrayMap<IBinder, Integer> mOwnerUids = new ArrayMap<>();
+
     private final int mMaxDevices;
     private final int mMaxDevicesPerPackage;
     private final SparseIntArray mNoOfDevicesPerPackage = new SparseIntArray();
@@ -194,6 +201,7 @@
         mVirtualDisplayDevices.put(appToken, device);
         if (getFeatureFlags().isVirtualDisplayLimitEnabled()) {
             mNoOfDevicesPerPackage.put(ownerUid, noOfDevices + 1);
+            mOwnerUids.put(appToken, ownerUid);
         }
 
         try {
@@ -205,7 +213,7 @@
             appToken.linkToDeath(device, 0);
         } catch (RemoteException ex) {
             Slog.e(TAG, "Virtual Display: error while setting up VirtualDisplayDevice", ex);
-            removeVirtualDisplayDeviceLocked(appToken, ownerUid);
+            removeVirtualDisplayDeviceLocked(appToken);
             device.destroyLocked(false);
             return null;
         }
@@ -252,12 +260,10 @@
     /**
      * Release a virtual display that was previously created
      * @param appToken The token to identify the display
-     * @param ownerUid The UID of the package, used to keep track of and limit the number of
-     *                 displays created per package
      * @return The display device that has been removed
      */
-    public DisplayDevice releaseVirtualDisplayLocked(IBinder appToken, int ownerUid) {
-        VirtualDisplayDevice device = removeVirtualDisplayDeviceLocked(appToken, ownerUid);
+    public DisplayDevice releaseVirtualDisplayLocked(IBinder appToken) {
+        VirtualDisplayDevice device = removeVirtualDisplayDeviceLocked(appToken);
         if (device != null) {
             Slog.v(TAG, "Release VirtualDisplay " + device.mName);
             device.destroyLocked(true);
@@ -299,11 +305,13 @@
         }
     }
 
-    private VirtualDisplayDevice removeVirtualDisplayDeviceLocked(IBinder appToken, int ownerUid) {
-        int noOfDevices = mNoOfDevicesPerPackage.get(ownerUid, /* valueIfKeyNotFound= */ 0);
+    private VirtualDisplayDevice removeVirtualDisplayDeviceLocked(IBinder appToken) {
         if (getFeatureFlags().isVirtualDisplayLimitEnabled()) {
+            int ownerUid = mOwnerUids.get(appToken);
+            int noOfDevices = mNoOfDevicesPerPackage.get(ownerUid, /* valueIfKeyNotFound= */ 0);
             if (noOfDevices <= 1) {
                 mNoOfDevicesPerPackage.delete(ownerUid);
+                mOwnerUids.remove(appToken);
             } else {
                 mNoOfDevicesPerPackage.put(ownerUid, noOfDevices - 1);
             }
@@ -378,7 +386,7 @@
         @Override
         public void binderDied() {
             synchronized (getSyncRoot()) {
-                removeVirtualDisplayDeviceLocked(mAppToken, mOwnerUid);
+                removeVirtualDisplayDeviceLocked(mAppToken);
                 Slog.i(TAG, "Virtual display device released because application token died: "
                     + mOwnerPackageName);
                 destroyLocked(false);
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 585fc44..78bd41b 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -93,6 +93,10 @@
             com.android.graphics.surfaceflinger.flags.Flags.FLAG_ENABLE_SMALL_AREA_DETECTION,
             com.android.graphics.surfaceflinger.flags.Flags::enableSmallAreaDetection);
 
+    private final FlagState mDisplayConfigErrorHalFlagState = new FlagState(
+            com.android.graphics.surfaceflinger.flags.Flags.FLAG_DISPLAY_CONFIG_ERROR_HAL,
+            com.android.graphics.surfaceflinger.flags.Flags::displayConfigErrorHal);
+
     private final FlagState mBrightnessIntRangeUserPerceptionFlagState = new FlagState(
             Flags.FLAG_BRIGHTNESS_INT_RANGE_USER_PERCEPTION,
             Flags::brightnessIntRangeUserPerception);
@@ -361,6 +365,10 @@
         return mSmallAreaDetectionFlagState.isEnabled();
     }
 
+    public boolean isDisplayConfigErrorHalEnabled() {
+        return mDisplayConfigErrorHalFlagState.isEnabled();
+    }
+
     public boolean isBrightnessIntRangeUserPerceptionEnabled() {
         return mBrightnessIntRangeUserPerceptionFlagState.isEnabled();
     }
@@ -591,6 +599,7 @@
         pw.println(" " + mPowerThrottlingClamperFlagState);
         pw.println(" " + mEvenDimmerFlagState);
         pw.println(" " + mSmallAreaDetectionFlagState);
+        pw.println(" " + mDisplayConfigErrorHalFlagState);
         pw.println(" " + mBrightnessIntRangeUserPerceptionFlagState);
         pw.println(" " + mRestrictDisplayModes);
         pw.println(" " + mBrightnessWearBedtimeModeClamperFlagState);
diff --git a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
index 8423e19..02e2882 100644
--- a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
@@ -136,6 +136,7 @@
     private final ProximitySensorObserver mSensorObserver;
     private final HbmObserver mHbmObserver;
     private final SkinThermalStatusObserver mSkinThermalStatusObserver;
+    private final ModeChangeObserver mModeChangeObserver;
 
     @Nullable
     private final SystemRequestObserver mSystemRequestObserver;
@@ -247,6 +248,7 @@
         mDisplayObserver = new DisplayObserver(context, handler, mVotesStorage, injector);
         mSensorObserver = new ProximitySensorObserver(mVotesStorage, injector);
         mSkinThermalStatusObserver = new SkinThermalStatusObserver(injector, mVotesStorage);
+        mModeChangeObserver = new ModeChangeObserver(mVotesStorage, injector, handler.getLooper());
         mHbmObserver = new HbmObserver(injector, mVotesStorage, BackgroundThread.getHandler(),
                 mDeviceConfigDisplaySettings);
         if (displayManagerFlags.isRestrictDisplayModesEnabled()) {
@@ -275,6 +277,9 @@
         mSensorObserver.observe();
         mHbmObserver.observe();
         mSkinThermalStatusObserver.observe();
+        if (mDisplayManagerFlags.isDisplayConfigErrorHalEnabled()) {
+            mModeChangeObserver.observe();
+        }
         synchronized (mLock) {
             // We may have a listener already registered before the call to start, so go ahead and
             // notify them to pick up our newly initialized state.
diff --git a/services/core/java/com/android/server/display/mode/ModeChangeObserver.java b/services/core/java/com/android/server/display/mode/ModeChangeObserver.java
new file mode 100644
index 0000000..bbc13cc
--- /dev/null
+++ b/services/core/java/com/android/server/display/mode/ModeChangeObserver.java
@@ -0,0 +1,108 @@
+/*
+ * 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.display.mode;
+
+import android.os.Looper;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.view.Display;
+import android.view.DisplayAddress;
+import android.view.DisplayEventReceiver;
+
+import com.android.internal.annotations.KeepForWeakReference;
+
+import java.util.HashSet;
+import java.util.Set;
+
+final class ModeChangeObserver {
+    private static final String TAG = "ModeChangeObserver";
+
+    private final VotesStorage mVotesStorage;
+    private final DisplayModeDirector.Injector mInjector;
+
+    @SuppressWarnings("unused")
+    @KeepForWeakReference
+    private DisplayEventReceiver mModeChangeListener;
+    private final SparseArray<Set<Integer>> mRejectedModesByDisplay = new SparseArray<>();
+    private Looper mLooper;
+
+    ModeChangeObserver(VotesStorage votesStorage, DisplayModeDirector.Injector injector,
+                    Looper looper) {
+        mVotesStorage = votesStorage;
+        mInjector = injector;
+        mLooper = looper;
+    }
+
+    void observe() {
+        mModeChangeListener = new DisplayEventReceiver(mLooper) {
+            @Override
+            public void onModeRejected(long physicalDisplayId, int modeId) {
+                Slog.d(TAG, "Mode Rejected event received");
+                int displayId = getLogicalDisplayId(physicalDisplayId);
+                if (displayId < 0) {
+                    Slog.e(TAG, "Logical Display Id not found");
+                    return;
+                }
+                populateRejectedModesListByDisplay(displayId, modeId);
+            }
+
+            @Override
+            public void onHotplug(long timestampNanos, long physicalDisplayId, boolean connected) {
+                Slog.d(TAG, "Hotplug event received");
+                if (!connected) {
+                    int displayId = getLogicalDisplayId(physicalDisplayId);
+                    if (displayId < 0) {
+                        Slog.e(TAG, "Logical Display Id not found");
+                        return;
+                    }
+                    clearRejectedModesListByDisplay(displayId);
+                }
+            }
+        };
+    }
+
+    private int getLogicalDisplayId(long rejectedModePhysicalDisplayId) {
+        Display[] displays = mInjector.getDisplays();
+
+        for (Display display : displays) {
+            DisplayAddress address = display.getAddress();
+            if (address instanceof DisplayAddress.Physical physical) {
+                long physicalDisplayId = physical.getPhysicalDisplayId();
+                if (physicalDisplayId == rejectedModePhysicalDisplayId) {
+                    return display.getDisplayId();
+                }
+            }
+        }
+        return -1;
+    }
+
+    private void populateRejectedModesListByDisplay(int displayId, int rejectedModeId) {
+        Set<Integer> alreadyRejectedModes = mRejectedModesByDisplay.get(displayId);
+        if (alreadyRejectedModes == null) {
+            alreadyRejectedModes = new HashSet<>();
+            mRejectedModesByDisplay.put(displayId, alreadyRejectedModes);
+        }
+        alreadyRejectedModes.add(rejectedModeId);
+        mVotesStorage.updateVote(displayId, Vote.PRIORITY_REJECTED_MODES,
+                Vote.forRejectedModes(alreadyRejectedModes));
+    }
+
+    private void clearRejectedModesListByDisplay(int displayId) {
+        mRejectedModesByDisplay.remove(displayId);
+        mVotesStorage.updateVote(displayId, Vote.PRIORITY_REJECTED_MODES, null);
+    }
+}
diff --git a/services/core/java/com/android/server/display/mode/RejectedModesVote.java b/services/core/java/com/android/server/display/mode/RejectedModesVote.java
new file mode 100644
index 0000000..db8c85278
--- /dev/null
+++ b/services/core/java/com/android/server/display/mode/RejectedModesVote.java
@@ -0,0 +1,40 @@
+/*
+ * 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.display.mode;
+
+import android.annotation.NonNull;
+
+import java.util.Collections;
+import java.util.Set;
+
+public class RejectedModesVote implements Vote {
+
+    final Set<Integer> mModeIds;
+
+    RejectedModesVote(Set<Integer> modeIds) {
+        mModeIds = Collections.unmodifiableSet(modeIds);
+    }
+    @Override
+    public void updateSummary(@NonNull VoteSummary summary) {
+        summary.rejectedModeIds.addAll(mModeIds);
+    }
+
+    @Override
+    public String toString() {
+        return "RejectedModesVote{ mModeIds=" + mModeIds + " }";
+    }
+}
diff --git a/services/core/java/com/android/server/display/mode/Vote.java b/services/core/java/com/android/server/display/mode/Vote.java
index f5abb05..428cced 100644
--- a/services/core/java/com/android/server/display/mode/Vote.java
+++ b/services/core/java/com/android/server/display/mode/Vote.java
@@ -25,6 +25,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
 interface Vote {
     // DEFAULT_RENDER_FRAME_RATE votes for render frame rate [0, DEFAULT]. As the lowest
@@ -82,68 +83,73 @@
 
     int PRIORITY_APP_REQUEST_SIZE = 7;
 
+    // PRIORITY_REJECTED_MODES rejects the modes for which the mode config failed
+    // so that the modeset can be retried for next available mode after filtering
+    // out the rejected modes for the connected display
+    int PRIORITY_REJECTED_MODES = 8;
+
     // PRIORITY_USER_SETTING_PEAK_REFRESH_RATE restricts physical refresh rate to
     // [0, max(PEAK, MIN)], depending on user settings peakRR/minRR values
-    int PRIORITY_USER_SETTING_PEAK_REFRESH_RATE = 8;
+    int PRIORITY_USER_SETTING_PEAK_REFRESH_RATE = 9;
 
     // PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE has a higher priority than
     // PRIORITY_USER_SETTING_PEAK_REFRESH_RATE and will limit render rate to [0, max(PEAK, MIN)]
     // in case physical refresh rate vote is discarded (due to other high priority votes),
     // render rate vote can still apply
-    int PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE = 9;
+    int PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE = 10;
 
     // Restrict all displays physical refresh rate to 60Hz when external display is connected.
     // It votes [59Hz, 61Hz].
-    int PRIORITY_SYNCHRONIZED_REFRESH_RATE = 10;
+    int PRIORITY_SYNCHRONIZED_REFRESH_RATE = 11;
 
     // PRIORITY_SYNCHRONIZED_RENDER_FRAME_RATE has a higher priority than
     // PRIORITY_SYNCHRONIZED_REFRESH_RATE and will limit render rate to [59Hz, 61Hz].
     // In case physical refresh rate vote discarded (due to physical refresh rate not supported),
     // render rate vote can still apply.
-    int PRIORITY_SYNCHRONIZED_RENDER_FRAME_RATE = 11;
+    int PRIORITY_SYNCHRONIZED_RENDER_FRAME_RATE = 12;
 
     // Restrict displays max available resolution and refresh rates. It votes [0, LIMIT]
-    int PRIORITY_LIMIT_MODE = 12;
+    int PRIORITY_LIMIT_MODE = 13;
 
     // To avoid delay in switching between 60HZ -> 90HZ when activating LHBM, set refresh
     // rate to max value (same as for PRIORITY_UDFPS) on lock screen
-    int PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE = 13;
+    int PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE = 14;
 
     // For concurrent displays we want to limit refresh rate on all displays
-    int PRIORITY_LAYOUT_LIMITED_REFRESH_RATE = 14;
+    int PRIORITY_LAYOUT_LIMITED_REFRESH_RATE = 15;
 
     // For concurrent displays we want to limit refresh rate on all displays
-    int PRIORITY_LAYOUT_LIMITED_FRAME_RATE = 15;
+    int PRIORITY_LAYOUT_LIMITED_FRAME_RATE = 16;
 
     // For internal application to limit display modes to specific ids
-    int PRIORITY_SYSTEM_REQUESTED_MODES = 16;
+    int PRIORITY_SYSTEM_REQUESTED_MODES = 17;
 
     // PRIORITY_LOW_POWER_MODE_MODES limits display modes to specific refreshRate-vsync pairs if
     // Settings.Global.LOW_POWER_MODE is on.
     // Lower priority that PRIORITY_LOW_POWER_MODE_RENDER_RATE and if discarded (due to other
     // higher priority votes), render rate limit can still apply
-    int PRIORITY_LOW_POWER_MODE_MODES = 17;
+    int PRIORITY_LOW_POWER_MODE_MODES = 18;
 
     // PRIORITY_LOW_POWER_MODE_RENDER_RATE force the render frame rate to [0, 60HZ] if
     // Settings.Global.LOW_POWER_MODE is on.
-    int PRIORITY_LOW_POWER_MODE_RENDER_RATE = 18;
+    int PRIORITY_LOW_POWER_MODE_RENDER_RATE = 19;
 
     // PRIORITY_FLICKER_REFRESH_RATE_SWITCH votes for disabling refresh rate switching. If the
     // higher priority voters' result is a range, it will fix the rate to a single choice.
     // It's used to avoid refresh rate switches in certain conditions which may result in the
     // user seeing the display flickering when the switches occur.
-    int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 19;
+    int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 20;
 
     // Force display to [0, 60HZ] if skin temperature is at or above CRITICAL.
-    int PRIORITY_SKIN_TEMPERATURE = 20;
+    int PRIORITY_SKIN_TEMPERATURE = 21;
 
     // The proximity sensor needs the refresh rate to be locked in order to function, so this is
     // set to a high priority.
-    int PRIORITY_PROXIMITY = 21;
+    int PRIORITY_PROXIMITY = 22;
 
     // The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order
     // to function, so this needs to be the highest priority of all votes.
-    int PRIORITY_UDFPS = 22;
+    int PRIORITY_UDFPS = 23;
 
     @IntDef(prefix = { "PRIORITY_" }, value = {
             PRIORITY_DEFAULT_RENDER_FRAME_RATE,
@@ -154,6 +160,7 @@
             PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE,
             PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE,
             PRIORITY_APP_REQUEST_SIZE,
+            PRIORITY_REJECTED_MODES,
             PRIORITY_USER_SETTING_PEAK_REFRESH_RATE,
             PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE,
             PRIORITY_SYNCHRONIZED_REFRESH_RATE,
@@ -245,6 +252,10 @@
         return new SupportedModesVote(modeIds);
     }
 
+    static Vote forRejectedModes(Set<Integer> modeIds) {
+        return new RejectedModesVote(modeIds);
+    }
+
     static String priorityToString(int priority) {
         switch (priority) {
             case PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE:
@@ -253,6 +264,8 @@
                 return "PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE";
             case PRIORITY_APP_REQUEST_SIZE:
                 return "PRIORITY_APP_REQUEST_SIZE";
+            case PRIORITY_REJECTED_MODES:
+                return "PRIORITY_REJECTED_MODES";
             case PRIORITY_DEFAULT_RENDER_FRAME_RATE:
                 return "PRIORITY_DEFAULT_REFRESH_RATE";
             case PRIORITY_FLICKER_REFRESH_RATE:
diff --git a/services/core/java/com/android/server/display/mode/VoteSummary.java b/services/core/java/com/android/server/display/mode/VoteSummary.java
index 00a9226..4166493 100644
--- a/services/core/java/com/android/server/display/mode/VoteSummary.java
+++ b/services/core/java/com/android/server/display/mode/VoteSummary.java
@@ -55,6 +55,11 @@
     @Nullable
     public List<Integer> supportedModeIds;
 
+    /**
+     * set of rejected modes due to mode config failure for connected display
+     */
+    public Set<Integer> rejectedModeIds = new HashSet<>();
+
     final boolean mIsDisplayResolutionRangeVotingEnabled;
 
     private final boolean mSupportedModesVoteEnabled;
@@ -132,6 +137,9 @@
             if (!validateModeSupported(mode)) {
                 continue;
             }
+            if (!validateModeRejected(mode)) {
+                continue;
+            }
             if (!validateModeSize(mode)) {
                 continue;
             }
@@ -285,6 +293,22 @@
         return false;
     }
 
+    private boolean validateModeRejected(Display.Mode mode) {
+        if (rejectedModeIds == null) {
+            return true;
+        }
+        if (!rejectedModeIds.contains(mode.getModeId())) {
+            return true;
+        }
+        if (mLoggingEnabled) {
+            Slog.w(TAG, "Discarding mode" + mode.getModeId()
+                    + ", is a rejectedMode"
+                    + ": mode.modeId=" + mode.getModeId()
+                    + ", rejectedModeIds=" + rejectedModeIds);
+        }
+        return false;
+    }
+
     private boolean validateRefreshRatesSupported(Display.Mode mode) {
         if (supportedRefreshRates == null || !mSupportedModesVoteEnabled) {
             return true;
@@ -397,6 +421,7 @@
         requestedRefreshRates.clear();
         supportedRefreshRates = null;
         supportedModeIds = null;
+        rejectedModeIds.clear();
         if (mLoggingEnabled) {
             Slog.i(TAG, "Summary reset: " + this);
         }
@@ -421,6 +446,7 @@
                 + ", requestRefreshRates=" + requestedRefreshRates
                 + ", supportedRefreshRates=" + supportedRefreshRates
                 + ", supportedModeIds=" + supportedModeIds
+                + ", rejectedModeIds=" + rejectedModeIds
                 + ", mIsDisplayResolutionRangeVotingEnabled="
                 + mIsDisplayResolutionRangeVotingEnabled
                 + ", mSupportedModesVoteEnabled=" + mSupportedModesVoteEnabled
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java b/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
index 236333e..18ae044 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
@@ -303,6 +303,10 @@
         return mSource.getDeviceInfo().getPhysicalAddress();
     }
 
+    protected final int getServicePath() {
+        return mService.getPhysicalAddress();
+    }
+
     protected final void sendUserControlPressedAndReleased(int targetAddress, int uiCommand) {
         mSource.sendUserControlPressedAndReleased(targetAddress, uiCommand);
     }
diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
index 256905d..9f6322d9 100644
--- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
+++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
@@ -152,7 +152,8 @@
         // If the device wasn´t the active source yet,
         // this makes it the active source and wakes it up.
         mSource.mService.setAndBroadcastActiveSourceFromOneDeviceType(
-                mTargetAddress, getSourcePath(), "OneTouchPlayAction#broadcastActiveSource()");
+                mTargetAddress, getServicePath(),
+                "OneTouchPlayAction#broadcastActiveSource()");
         // When OneTouchPlay is called, client side should be responsible to send out the intent
         // of which internal source, for example YouTube, it would like to switch to.
         // Here we only update the active port and the active source records in the local
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index aee5e7f..559b4ae 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -34,6 +34,7 @@
 import android.annotation.Nullable;
 import android.annotation.PermissionManuallyEnforced;
 import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
 import android.annotation.UserIdInt;
 import android.app.ActivityManagerInternal;
 import android.bluetooth.BluetoothAdapter;
@@ -2625,38 +2626,14 @@
         return mWindowManagerCallbacks.interceptUnhandledKey(event, focus);
     }
 
+    @SuppressLint("MissingPermission")
     private void initKeyGestures() {
         InputManager im = Objects.requireNonNull(mContext.getSystemService(InputManager.class));
         im.registerKeyGestureEventHandler(new InputManager.KeyGestureEventHandler() {
             @Override
             public boolean handleKeyGestureEvent(@NonNull KeyGestureEvent event,
                     @Nullable IBinder focussedToken) {
-                int deviceId = event.getDeviceId();
-                boolean complete = event.getAction() == KeyGestureEvent.ACTION_GESTURE_COMPLETE
-                        && !event.isCancelled();
-                switch (event.getKeyGestureType()) {
-                    case KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP:
-                        if (complete) {
-                            mKeyboardBacklightController.incrementKeyboardBacklight(deviceId);
-                        }
-                        return true;
-                    case KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN:
-                        if (complete) {
-                            mKeyboardBacklightController.decrementKeyboardBacklight(deviceId);
-                        }
-                        return true;
-                    case KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE:
-                        // TODO(b/367748270): Add functionality to turn keyboard backlight on/off.
-                        return true;
-                    case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK:
-                        if (complete) {
-                            mNative.toggleCapsLock(deviceId);
-                        }
-                        return true;
-                    default:
-                        return false;
-
-                }
+                return InputManagerService.this.handleKeyGestureEvent(event);
             }
 
             @Override
@@ -2666,6 +2643,10 @@
                     case KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN:
                     case KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE:
                     case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK:
+                    case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS:
+                    case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_BOUNCE_KEYS:
+                    case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS:
+                    case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_STICKY_KEYS:
                         return true;
                     default:
                         return false;
@@ -2675,6 +2656,73 @@
         });
     }
 
+    @SuppressLint("MissingPermission")
+    @VisibleForTesting
+    boolean handleKeyGestureEvent(@NonNull KeyGestureEvent event) {
+        int deviceId = event.getDeviceId();
+        boolean complete = event.getAction() == KeyGestureEvent.ACTION_GESTURE_COMPLETE
+                && !event.isCancelled();
+        switch (event.getKeyGestureType()) {
+            case KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP:
+                if (complete) {
+                    mKeyboardBacklightController.incrementKeyboardBacklight(deviceId);
+                }
+                return true;
+            case KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN:
+                if (complete) {
+                    mKeyboardBacklightController.decrementKeyboardBacklight(deviceId);
+                }
+                return true;
+            case KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE:
+                // TODO(b/367748270): Add functionality to turn keyboard backlight on/off.
+                return true;
+            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK:
+                if (complete) {
+                    mNative.toggleCapsLock(deviceId);
+                }
+                return true;
+            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_BOUNCE_KEYS:
+                if (complete && InputSettings.isAccessibilityBounceKeysFeatureEnabled()) {
+                    final boolean bounceKeysEnabled =
+                            InputSettings.isAccessibilityBounceKeysEnabled(mContext);
+                    InputSettings.setAccessibilityBounceKeysThreshold(mContext,
+                            bounceKeysEnabled ? 0
+                                    : InputSettings.DEFAULT_BOUNCE_KEYS_THRESHOLD_MILLIS);
+                    return true;
+                }
+                break;
+            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS:
+                if (complete && InputSettings.isAccessibilityMouseKeysFeatureFlagEnabled()) {
+                    final boolean mouseKeysEnabled = InputSettings.isAccessibilityMouseKeysEnabled(
+                            mContext);
+                    InputSettings.setAccessibilityMouseKeysEnabled(mContext, !mouseKeysEnabled);
+                    return true;
+                }
+                break;
+            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_STICKY_KEYS:
+                if (complete && InputSettings.isAccessibilityStickyKeysFeatureEnabled()) {
+                    final boolean stickyKeysEnabled =
+                            InputSettings.isAccessibilityStickyKeysEnabled(mContext);
+                    InputSettings.setAccessibilityStickyKeysEnabled(mContext, !stickyKeysEnabled);
+                    return true;
+                }
+                break;
+            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS:
+                if (complete && InputSettings.isAccessibilitySlowKeysFeatureFlagEnabled()) {
+                    final boolean slowKeysEnabled =
+                            InputSettings.isAccessibilitySlowKeysEnabled(mContext);
+                    InputSettings.setAccessibilitySlowKeysThreshold(mContext,
+                            slowKeysEnabled ? 0 : InputSettings.DEFAULT_SLOW_KEYS_THRESHOLD_MILLIS);
+                    return true;
+                }
+                break;
+            default:
+                return false;
+
+        }
+        return false;
+    }
+
     // Native callback.
     @SuppressWarnings("unused")
     private void onPointerDownOutsideFocus(IBinder touchedToken) {
diff --git a/services/core/java/com/android/server/input/KeyGestureController.java b/services/core/java/com/android/server/input/KeyGestureController.java
index 99c01ce..5f7ad27 100644
--- a/services/core/java/com/android/server/input/KeyGestureController.java
+++ b/services/core/java/com/android/server/input/KeyGestureController.java
@@ -801,7 +801,15 @@
                         + " interceptKeyBeforeQueueing");
                 return true;
             case KeyEvent.KEYCODE_DO_NOT_DISTURB:
-                // TODO(b/365920375): Implement 25Q2 keycode implementation in system
+                if (enableNew25q2Keycodes()) {
+                    if (firstDown) {
+                        handleKeyGesture(deviceId, new int[]{KeyEvent.KEYCODE_DO_NOT_DISTURB},
+                                /* modifierState = */0,
+                                KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB,
+                                KeyGestureEvent.ACTION_GESTURE_COMPLETE, displayId, focusedToken,
+                                /* flags = */0, /* appLaunchData = */null);
+                    }
+                }
                 return true;
         }
 
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 02dd884..6800142 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -1209,8 +1209,14 @@
         // Hide soft input before user switch task since switch task may block main handler a while
         // and delayed the hideCurrentInputLocked().
         final var userData = getUserData(userId);
-        hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow, 0 /* flags */,
-                SoftInputShowHideReason.HIDE_SWITCH_USER, userId);
+        if (Flags.refactorInsetsController()) {
+            final var statsToken = createStatsTokenForFocusedClient(false /* show */,
+                    SoftInputShowHideReason.HIDE_SWITCH_USER, userId);
+            setImeVisibilityOnFocusedWindowClient(false, userData, statsToken);
+        } else {
+            hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow, 0 /* flags */,
+                    SoftInputShowHideReason.HIDE_SWITCH_USER, userId);
+        }
         final UserSwitchHandlerTask task = new UserSwitchHandlerTask(this, userId,
                 clientToBeReset);
         mUserSwitchHandlerTask = task;
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java
index 4a533f4..9b9d52a 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java
@@ -18,10 +18,14 @@
 
 import android.content.Context;
 import android.hardware.contexthub.EndpointInfo;
+import android.hardware.contexthub.ErrorCode;
 import android.hardware.contexthub.HubEndpointInfo;
 import android.hardware.contexthub.HubMessage;
 import android.hardware.contexthub.IContextHubEndpoint;
 import android.hardware.contexthub.IContextHubEndpointCallback;
+import android.hardware.contexthub.Message;
+import android.hardware.contexthub.MessageDeliveryStatus;
+import android.hardware.location.ContextHubTransaction;
 import android.hardware.location.IContextHubTransactionCallback;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -78,18 +82,28 @@
     @GuardedBy("mOpenSessionLock")
     private final Set<Integer> mActiveRemoteSessionIds = new HashSet<>();
 
+    /** The package name of the app that created the endpoint */
+    private final String mPackageName;
+
+    /* Transaction manager used for sending reliable messages */
+    private final ContextHubTransactionManager mTransactionManager;
+
     /* package */ ContextHubEndpointBroker(
             Context context,
             IContextHubWrapper contextHubProxy,
             ContextHubEndpointManager endpointManager,
             EndpointInfo halEndpointInfo,
-            IContextHubEndpointCallback callback) {
+            IContextHubEndpointCallback callback,
+            String packageName,
+            ContextHubTransactionManager transactionManager) {
         mContext = context;
         mContextHubProxy = contextHubProxy;
         mEndpointManager = endpointManager;
         mEndpointInfo = new HubEndpointInfo(halEndpointInfo);
         mHalEndpointInfo = halEndpointInfo;
         mContextHubEndpointCallback = callback;
+        mPackageName = packageName;
+        mTransactionManager = transactionManager;
     }
 
     @Override
@@ -175,18 +189,65 @@
     @Override
     public void sendMessage(
             int sessionId, HubMessage message, IContextHubTransactionCallback callback) {
-        // TODO(b/381102453): Implement this
+        ContextHubServiceUtil.checkPermissions(mContext);
+        Message halMessage = ContextHubServiceUtil.createHalMessage(message);
+        synchronized (mOpenSessionLock) {
+            if (!mActiveSessionIds.contains(sessionId)
+                    && !mActiveRemoteSessionIds.contains(sessionId)) {
+                throw new SecurityException(
+                        "sendMessage called on inactive session (id= " + sessionId + ")");
+            }
+        }
+
+        // TODO(b/381102453): Handle permissions
+        if (callback == null) {
+            try {
+                mContextHubProxy.sendMessageToEndpoint(sessionId, halMessage);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Exception while sending message on session " + sessionId, e);
+            }
+        } else {
+            ContextHubServiceTransaction transaction =
+                    mTransactionManager.createSessionMessageTransaction(
+                            sessionId, halMessage, mPackageName, callback);
+            try {
+                mTransactionManager.addTransaction(transaction);
+            } catch (IllegalStateException e) {
+                Log.e(
+                        TAG,
+                        "Unable to add a transaction in sendMessageToEndpoint "
+                                + "(session ID = "
+                                + sessionId
+                                + ")",
+                        e);
+                transaction.onTransactionComplete(
+                        ContextHubTransaction.RESULT_FAILED_SERVICE_INTERNAL_FAILURE);
+            }
+        }
     }
 
     @Override
     public void sendMessageDeliveryStatus(int sessionId, int messageSeqNumber, byte errorCode) {
-        // TODO(b/381102453): Implement this
+        ContextHubServiceUtil.checkPermissions(mContext);
+        MessageDeliveryStatus status = new MessageDeliveryStatus();
+        status.messageSequenceNumber = messageSeqNumber;
+        status.errorCode = errorCode;
+        try {
+            mContextHubProxy.sendMessageDeliveryStatusToEndpoint(sessionId, status);
+        } catch (RemoteException e) {
+            Log.w(
+                    TAG,
+                    "Exception while sending message delivery status on session " + sessionId,
+                    e);
+        }
     }
 
     /** Invoked when the underlying binder of this broker has died at the client process. */
     @Override
     public void binderDied() {
-        unregister();
+        if (mIsRegistered.get()) {
+            unregister();
+        }
     }
 
     /* package */ void attachDeathRecipient() throws RemoteException {
@@ -236,6 +297,21 @@
         }
     }
 
+    /* package */ void onMessageReceived(int sessionId, HubMessage message) {
+        if (mContextHubEndpointCallback != null) {
+            try {
+                mContextHubEndpointCallback.onMessageReceived(sessionId, message);
+            } catch (RemoteException e) {
+                Log.e(TAG, "RemoteException while calling onMessageReceived", e);
+            }
+        }
+    }
+
+    /* package */ void onMessageDeliveryStatusReceived(
+            int sessionId, int sequenceNumber, byte errorCode) {
+        mTransactionManager.onMessageDeliveryResponse(sequenceNumber, errorCode == ErrorCode.OK);
+    }
+
     /* package */ boolean hasSessionId(int sessionId) {
         synchronized (mOpenSessionLock) {
             return mPendingSessionIds.contains(sessionId)
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java
index 8c5095f3..07df7f9 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.hardware.contexthub.EndpointInfo;
 import android.hardware.contexthub.HubEndpointInfo;
+import android.hardware.contexthub.HubMessage;
 import android.hardware.contexthub.IContextHubEndpoint;
 import android.hardware.contexthub.IContextHubEndpointCallback;
 import android.os.RemoteException;
@@ -59,14 +60,20 @@
 
     private final HubInfoRegistry mHubInfoRegistry;
 
+    private final ContextHubTransactionManager mTransactionManager;
+
     /** A map of endpoint IDs to brokers currently registered. */
     private final Map<Long, ContextHubEndpointBroker> mEndpointMap = new ConcurrentHashMap<>();
 
     /** Variables for managing endpoint ID creation */
     private final Object mEndpointLock = new Object();
 
+    /**
+     * The next available endpoint ID to register. Per EndpointId.aidl definition, dynamic
+     * endpoint IDs must have the left-most bit as 1, and the values 0/-1 are invalid.
+     */
     @GuardedBy("mEndpointLock")
-    private long mNextEndpointId = 0;
+    private long mNextEndpointId = -2;
 
     /** The minimum session ID reservable by endpoints (retrieved from HAL) */
     private final int mMinSessionId;
@@ -89,10 +96,14 @@
     private final boolean mSessionIdsValid;
 
     /* package */ ContextHubEndpointManager(
-            Context context, IContextHubWrapper contextHubProxy, HubInfoRegistry hubInfoRegistry) {
+            Context context,
+            IContextHubWrapper contextHubProxy,
+            HubInfoRegistry hubInfoRegistry,
+            ContextHubTransactionManager transactionManager) {
         mContext = context;
         mContextHubProxy = contextHubProxy;
         mHubInfoRegistry = hubInfoRegistry;
+        mTransactionManager = transactionManager;
         int[] range = null;
         try {
             range = mContextHubProxy.requestSessionIdRange(SERVICE_SESSION_RANGE);
@@ -128,11 +139,14 @@
      *
      * @param pendingEndpointInfo the object describing the endpoint being registered
      * @param callback the callback interface of the endpoint to register
+     * @param packageName the name of the package of the calling client
      * @return the endpoint interface
      * @throws IllegalStateException if max number of endpoints have already registered
      */
     /* package */ IContextHubEndpoint registerEndpoint(
-            HubEndpointInfo pendingEndpointInfo, IContextHubEndpointCallback callback)
+            HubEndpointInfo pendingEndpointInfo,
+            IContextHubEndpointCallback callback,
+            String packageName)
             throws RemoteException {
         if (!mSessionIdsValid) {
             throw new IllegalStateException("ContextHubEndpointManager failed to initialize");
@@ -154,7 +168,9 @@
                         mContextHubProxy,
                         this /* endpointManager */,
                         halEndpointInfo,
-                        callback);
+                        callback,
+                        packageName,
+                        mTransactionManager);
         mEndpointMap.put(endpointId, broker);
 
         try {
@@ -279,13 +295,45 @@
         }
     }
 
+    @Override
+    public void onMessageReceived(int sessionId, HubMessage message) {
+        boolean callbackInvoked = false;
+        for (ContextHubEndpointBroker broker : mEndpointMap.values()) {
+            if (broker.hasSessionId(sessionId)) {
+                broker.onMessageReceived(sessionId, message);
+                callbackInvoked = true;
+                break;
+            }
+        }
+
+        if (!callbackInvoked) {
+            Log.w(TAG, "onMessageReceived: unknown session ID " + sessionId);
+        }
+    }
+
+    @Override
+    public void onMessageDeliveryStatusReceived(int sessionId, int sequenceNumber, byte errorCode) {
+        boolean callbackInvoked = false;
+        for (ContextHubEndpointBroker broker : mEndpointMap.values()) {
+            if (broker.hasSessionId(sessionId)) {
+                broker.onMessageDeliveryStatusReceived(sessionId, sequenceNumber, errorCode);
+                callbackInvoked = true;
+                break;
+            }
+        }
+
+        if (!callbackInvoked) {
+            Log.w(TAG, "onMessageDeliveryStatusReceived: unknown session ID " + sessionId);
+        }
+    }
+
     /** @return an available endpoint ID */
     private long getNewEndpointId() {
         synchronized (mEndpointLock) {
-            if (mNextEndpointId == Long.MAX_VALUE) {
+            if (mNextEndpointId >= 0) {
                 throw new IllegalStateException("Too many endpoints connected");
             }
-            return mNextEndpointId++;
+            return mNextEndpointId--;
         }
     }
 
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java b/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java
index 9d52c6a..f1f2217 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java
@@ -17,6 +17,7 @@
 
 import android.hardware.contexthub.EndpointId;
 import android.hardware.contexthub.HubEndpointInfo;
+import android.hardware.contexthub.HubMessage;
 import android.hardware.contexthub.IEndpointCallback;
 import android.hardware.contexthub.Message;
 import android.hardware.contexthub.MessageDeliveryStatus;
@@ -51,6 +52,12 @@
 
         /** Called when a requested endpoint open session is completed */
         void onEndpointSessionOpenComplete(int sessionId);
+
+        /** Called when a message is received for the session */
+        void onMessageReceived(int sessionId, HubMessage message);
+
+        /** Called when a message delivery status is received for the session */
+        void onMessageDeliveryStatusReceived(int sessionId, int sequenceNumber, byte errorCode);
     }
 
     ContextHubHalEndpointCallback(
@@ -84,13 +91,6 @@
     }
 
     @Override
-    public void onMessageReceived(int i, Message message) throws RemoteException {}
-
-    @Override
-    public void onMessageDeliveryStatusReceived(int i, MessageDeliveryStatus messageDeliveryStatus)
-            throws RemoteException {}
-
-    @Override
     public void onEndpointSessionOpenRequest(
             int i, EndpointId destination, EndpointId initiator, String s) throws RemoteException {
         HubEndpointInfo.HubEndpointIdentifier destinationId =
@@ -111,6 +111,19 @@
     }
 
     @Override
+    public void onMessageReceived(int i, Message message) throws RemoteException {
+        HubMessage hubMessage = ContextHubServiceUtil.createHubMessage(message);
+        mEndpointSessionCallback.onMessageReceived(i, hubMessage);
+    }
+
+    @Override
+    public void onMessageDeliveryStatusReceived(int i, MessageDeliveryStatus messageDeliveryStatus)
+            throws RemoteException {
+        mEndpointSessionCallback.onMessageDeliveryStatusReceived(
+                i, messageDeliveryStatus.messageSequenceNumber, messageDeliveryStatus.errorCode);
+    }
+
+    @Override
     public int getInterfaceVersion() throws RemoteException {
         return IEndpointCallback.VERSION;
     }
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
index 0b47a61..165f9d3 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -334,7 +334,8 @@
             try {
                 registry = new HubInfoRegistry(mContextHubWrapper);
                 mEndpointManager =
-                        new ContextHubEndpointManager(mContext, mContextHubWrapper, registry);
+                        new ContextHubEndpointManager(
+                                mContext, mContextHubWrapper, registry, mTransactionManager);
                 Log.i(TAG, "Enabling generic offload API");
             } catch (UnsupportedOperationException e) {
                 mEndpointManager = null;
@@ -794,14 +795,16 @@
     @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public IContextHubEndpoint registerEndpoint(
-            HubEndpointInfo pendingHubEndpointInfo, IContextHubEndpointCallback callback)
+            HubEndpointInfo pendingHubEndpointInfo,
+            IContextHubEndpointCallback callback,
+            String packageName)
             throws RemoteException {
         super.registerEndpoint_enforcePermission();
         if (mEndpointManager == null) {
-            Log.e(TAG, "ContextHubService.registerEndpoint: endpoint manager failed to initialize");
+            Log.e(TAG, "Endpoint manager failed to initialize");
             throw new UnsupportedOperationException("Endpoint registration is not supported");
         }
-        return mEndpointManager.registerEndpoint(pendingHubEndpointInfo, callback);
+        return mEndpointManager.registerEndpoint(pendingHubEndpointInfo, callback, packageName);
     }
 
     @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@@ -809,7 +812,8 @@
     public void registerEndpointDiscoveryCallbackId(
             long endpointId, IContextHubEndpointDiscoveryCallback callback) throws RemoteException {
         super.registerEndpointDiscoveryCallbackId_enforcePermission();
-        // TODO(b/375487784): Implement this
+        checkEndpointDiscoveryPreconditions();
+        mHubInfoRegistry.registerEndpointDiscoveryCallback(endpointId, callback);
     }
 
     @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@@ -818,7 +822,8 @@
             String serviceDescriptor, IContextHubEndpointDiscoveryCallback callback)
             throws RemoteException {
         super.registerEndpointDiscoveryCallbackDescriptor_enforcePermission();
-        // TODO(b/375487784): Implement this
+        checkEndpointDiscoveryPreconditions();
+        mHubInfoRegistry.registerEndpointDiscoveryCallback(serviceDescriptor, callback);
     }
 
     @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@@ -826,7 +831,15 @@
     public void unregisterEndpointDiscoveryCallback(IContextHubEndpointDiscoveryCallback callback)
             throws RemoteException {
         super.unregisterEndpointDiscoveryCallback_enforcePermission();
-        // TODO(b/375487784): Implement this
+        checkEndpointDiscoveryPreconditions();
+        mHubInfoRegistry.unregisterEndpointDiscoveryCallback(callback);
+    }
+
+    private void checkEndpointDiscoveryPreconditions() {
+        if (mHubInfoRegistry == null) {
+            Log.e(TAG, "Hub endpoint registry failed to initialize");
+            throw new UnsupportedOperationException("Endpoint discovery is not supported");
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java b/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java
index 3aea6d5..4e96b44 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java
@@ -16,6 +16,7 @@
 
 package com.android.server.location.contexthub;
 
+import android.chre.flags.Flags;
 import android.hardware.location.ContextHubTransaction;
 import android.hardware.location.NanoAppState;
 
@@ -46,7 +47,11 @@
     /** The number of times the transaction has been started (start function called). */
     private int mNumCompletedStartCalls;
 
-    private final short mHostEndpointId;
+    /**
+     * A unique identifier for the entity which owns this transaction, scoped by the transaction
+     * type.
+     */
+    private final int mOwnerId;
 
     private boolean mIsComplete = false;
 
@@ -59,7 +64,7 @@
         mNextRetryTime = Long.MAX_VALUE;
         mTimeoutTime = Long.MAX_VALUE;
         mNumCompletedStartCalls = 0;
-        mHostEndpointId = Short.MAX_VALUE;
+        mOwnerId = Integer.MAX_VALUE;
     }
 
     ContextHubServiceTransaction(int id, int type, long nanoAppId,
@@ -72,11 +77,11 @@
         mNextRetryTime = Long.MAX_VALUE;
         mTimeoutTime = Long.MAX_VALUE;
         mNumCompletedStartCalls = 0;
-        mHostEndpointId = Short.MAX_VALUE;
+        mOwnerId = Integer.MAX_VALUE;
     }
 
-    ContextHubServiceTransaction(int id, int type, String packageName,
-            int messageSequenceNumber, short hostEndpointId) {
+    ContextHubServiceTransaction(
+            int id, int type, String packageName, int messageSequenceNumber, int ownerId) {
         mTransactionId = id;
         mTransactionType = type;
         mNanoAppId = Long.MAX_VALUE;
@@ -85,7 +90,7 @@
         mNextRetryTime = Long.MAX_VALUE;
         mTimeoutTime = Long.MAX_VALUE;
         mNumCompletedStartCalls = 0;
-        mHostEndpointId = hostEndpointId;
+        mOwnerId = ownerId;
     }
 
     /**
@@ -147,8 +152,15 @@
         return mNumCompletedStartCalls;
     }
 
-    short getHostEndpointId() {
-        return mHostEndpointId;
+    /**
+     * @return A unique identifier for the entity owning this transaction.
+     */
+    long getOwnerId() {
+        if (Flags.offloadImplementation()) {
+            return ((long) mTransactionType << 32) | (0x00000000FFFFFFFFL & mOwnerId);
+        } else {
+            return mOwnerId;
+        }
     }
 
     /**
@@ -215,15 +227,16 @@
             out.append(", messageSequenceNumber = ");
             out.append(mMessageSequenceNumber);
         }
-        if (mTransactionType == ContextHubTransaction.TYPE_RELIABLE_MESSAGE) {
+        if (mTransactionType == ContextHubTransaction.TYPE_RELIABLE_MESSAGE
+                || mTransactionType == ContextHubTransaction.TYPE_HUB_MESSAGE_REQUIRES_RESPONSE) {
             out.append(", nextRetryTime = ");
             out.append(mNextRetryTime);
             out.append(", timeoutTime = ");
             out.append(mTimeoutTime);
             out.append(", numCompletedStartCalls = ");
             out.append(mNumCompletedStartCalls);
-            out.append(", hostEndpointId = ");
-            out.append(mHostEndpointId);
+            out.append(", ownerId = ");
+            out.append(getOwnerId());
         }
         out.append(")");
 
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java b/services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java
index 05be427..a215b46 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java
@@ -20,7 +20,9 @@
 import android.content.Context;
 import android.hardware.contexthub.EndpointInfo;
 import android.hardware.contexthub.HubEndpointInfo;
+import android.hardware.contexthub.HubMessage;
 import android.hardware.contexthub.HubServiceInfo;
+import android.hardware.contexthub.Message;
 import android.hardware.contexthub.V1_0.AsyncEventType;
 import android.hardware.contexthub.V1_0.ContextHubMsg;
 import android.hardware.contexthub.V1_0.HostEndPoint;
@@ -465,4 +467,39 @@
         }
         return outputInfo;
     }
+
+    /**
+     * Converts a HubMessage object to a AIDL HAL Message object.
+     *
+     * @param message the HubMessage message to convert
+     * @return the AIDL HAL message
+     */
+    /* package */
+    static Message createHalMessage(HubMessage message) {
+        Message outMessage = new Message();
+        outMessage.flags =
+                message.getDeliveryParams().isResponseRequired()
+                        ? Message.FLAG_REQUIRES_DELIVERY_STATUS
+                        : 0;
+        outMessage.permissions = new String[0];
+        outMessage.sequenceNumber = message.getMessageSequenceNumber();
+        outMessage.type = message.getMessageType();
+        outMessage.content = message.getMessageBody();
+        return outMessage;
+    }
+
+    /**
+     * Converts a AIDL HAL Message object to a HubMessage object.
+     *
+     * @param message the AIDL HAL Message message to convert
+     * @return the HubMessage
+     */
+    /* package */
+    static HubMessage createHubMessage(Message message) {
+        boolean isReliable = (message.flags & Message.FLAG_REQUIRES_DELIVERY_STATUS) != 0;
+        return HubMessage.createMessage(
+                message.type,
+                message.content,
+                HubMessage.DeliveryParams.makeBasic().setResponseRequired(isReliable));
+    }
 }
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
index ccfa61b..5dd40ea 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
@@ -17,6 +17,7 @@
 package com.android.server.location.contexthub;
 
 import android.chre.flags.Flags;
+import android.hardware.contexthub.Message;
 import android.hardware.location.ContextHubTransaction;
 import android.hardware.location.IContextHubTransactionCallback;
 import android.hardware.location.NanoAppBinary;
@@ -84,9 +85,9 @@
     protected final Map<Integer, ContextHubServiceTransaction> mReliableMessageTransactionMap =
             new HashMap<>();
 
-    /** A set of host endpoint IDs that have an active pending transaction. */
+    /** A set of IDs of transaction owners that have an active pending transaction. */
     @GuardedBy("mReliableMessageLock")
-    protected final Set<Short> mReliableMessageHostEndpointIdActiveSet = new HashSet<>();
+    protected final Set<Long> mReliableMessageOwnerIdActiveSet = new HashSet<>();
 
     protected final AtomicInteger mNextAvailableId = new AtomicInteger();
 
@@ -355,27 +356,32 @@
     /**
      * Creates a transaction to send a reliable message.
      *
-     * @param hostEndpointId      The ID of the host endpoint sending the message.
-     * @param contextHubId        The ID of the hub to send the message to.
-     * @param message             The message to send.
+     * @param ownerId The ID of the transaction owner.
+     * @param contextHubId The ID of the hub to send the message to.
+     * @param message The message to send.
      * @param transactionCallback The callback of the transactions.
-     * @param packageName         The host package associated with this transaction.
+     * @param packageName The host package associated with this transaction.
      * @return The generated transaction.
      */
     /* package */ ContextHubServiceTransaction createMessageTransaction(
-            short hostEndpointId, int contextHubId, NanoAppMessage message,
-            IContextHubTransactionCallback transactionCallback, String packageName) {
-        return new ContextHubServiceTransaction(mNextAvailableId.getAndIncrement(),
-                ContextHubTransaction.TYPE_RELIABLE_MESSAGE, packageName,
-                mNextAvailableMessageSequenceNumber.getAndIncrement(), hostEndpointId) {
+            short ownerId,
+            int contextHubId,
+            NanoAppMessage message,
+            IContextHubTransactionCallback transactionCallback,
+            String packageName) {
+        return new ContextHubServiceTransaction(
+                mNextAvailableId.getAndIncrement(),
+                ContextHubTransaction.TYPE_RELIABLE_MESSAGE,
+                packageName,
+                mNextAvailableMessageSequenceNumber.getAndIncrement(),
+                ownerId) {
             @Override
             /* package */ int onTransact() {
                 try {
                     message.setIsReliable(/* isReliable= */ true);
                     message.setMessageSequenceNumber(getMessageSequenceNumber());
 
-                    return mContextHubProxy.sendMessageToContextHub(hostEndpointId, contextHubId,
-                            message);
+                    return mContextHubProxy.sendMessageToContextHub(ownerId, contextHubId, message);
                 } catch (RemoteException e) {
                     Log.e(TAG, "RemoteException while trying to send a reliable message", e);
                     return ContextHubTransaction.RESULT_FAILED_UNKNOWN;
@@ -394,6 +400,48 @@
     }
 
     /**
+     * Creates a transaction to send a message through a session.
+     *
+     * @param sessionId The ID of the endpoint session the message should be sent through.
+     * @param message The message to send.
+     * @param transactionCallback The callback of the transactions.
+     * @return The generated transaction.
+     */
+    /* package */ ContextHubServiceTransaction createSessionMessageTransaction(
+            int sessionId,
+            Message message,
+            String packageName,
+            IContextHubTransactionCallback transactionCallback) {
+        return new ContextHubServiceTransaction(
+                mNextAvailableId.getAndIncrement(),
+                ContextHubTransaction.TYPE_HUB_MESSAGE_REQUIRES_RESPONSE,
+                packageName,
+                mNextAvailableMessageSequenceNumber.getAndIncrement(),
+                sessionId) {
+            @Override
+            /* package */ int onTransact() {
+                try {
+                    message.sequenceNumber = getMessageSequenceNumber();
+                    mContextHubProxy.sendMessageToEndpoint(sessionId, message);
+                    return ContextHubTransaction.RESULT_SUCCESS;
+                } catch (RemoteException e) {
+                    Log.e(TAG, "RemoteException while trying to send a session message", e);
+                    return ContextHubTransaction.RESULT_FAILED_UNKNOWN;
+                }
+            }
+
+            @Override
+            /* package */ void onTransactionComplete(@ContextHubTransaction.Result int result) {
+                try {
+                    transactionCallback.onTransactionComplete(result);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "RemoteException while calling client onTransactionComplete", e);
+                }
+            }
+        };
+    }
+
+    /**
      * Creates a transaction for querying for a list of nanoapps.
      *
      * @param contextHubId       the ID of the hub to query
@@ -452,9 +500,14 @@
             mTransactionRecordDeque.add(new TransactionRecord(transaction.toString()));
         }
 
-        if (Flags.reliableMessageRetrySupportService()
-                && transaction.getTransactionType()
-                        == ContextHubTransaction.TYPE_RELIABLE_MESSAGE) {
+        boolean isReliableMessage =
+                Flags.reliableMessageRetrySupportService()
+                        && (transaction.getTransactionType()
+                                == ContextHubTransaction.TYPE_RELIABLE_MESSAGE);
+        boolean isEndpointMessage =
+                (transaction.getTransactionType()
+                        == ContextHubTransaction.TYPE_HUB_MESSAGE_REQUIRES_RESPONSE);
+        if (isReliableMessage || isEndpointMessage) {
             synchronized (mReliableMessageLock) {
                 if (mReliableMessageTransactionMap.size() >= MAX_PENDING_REQUESTS) {
                     throw new IllegalStateException(
@@ -766,10 +819,10 @@
                         mReliableMessageTransactionMap.entrySet().iterator();
                 while (iter.hasNext()) {
                     ContextHubServiceTransaction transaction = iter.next().getValue();
-                    short hostEndpointId = transaction.getHostEndpointId();
+                    long ownerId = transaction.getOwnerId();
                     int numCompletedStartCalls = transaction.getNumCompletedStartCalls();
                     if (numCompletedStartCalls == 0
-                            && mReliableMessageHostEndpointIdActiveSet.contains(hostEndpointId)) {
+                            && mReliableMessageOwnerIdActiveSet.contains(ownerId)) {
                         continue;
                     }
 
@@ -871,7 +924,7 @@
         } else {
             iter.remove();
         }
-        mReliableMessageHostEndpointIdActiveSet.remove(transaction.getHostEndpointId());
+        mReliableMessageOwnerIdActiveSet.remove(transaction.getOwnerId());
     }
 
     /**
@@ -906,7 +959,7 @@
             transaction.setTimeoutTime(now + RELIABLE_MESSAGE_TIMEOUT.toNanos());
         }
         transaction.setNumCompletedStartCalls(numCompletedStartCalls + 1);
-        mReliableMessageHostEndpointIdActiveSet.add(transaction.getHostEndpointId());
+        mReliableMessageOwnerIdActiveSet.add(transaction.getOwnerId());
     }
 
     private int toStatsTransactionResult(@ContextHubTransaction.Result int result) {
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManagerOld.java b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManagerOld.java
index a67fa30..657375d 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManagerOld.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManagerOld.java
@@ -18,28 +18,14 @@
 
 import android.chre.flags.Flags;
 import android.hardware.location.ContextHubTransaction;
-import android.hardware.location.IContextHubTransactionCallback;
-import android.hardware.location.NanoAppBinary;
-import android.hardware.location.NanoAppMessage;
 import android.hardware.location.NanoAppState;
-import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.Log;
 
-import java.time.Duration;
-import java.util.ArrayDeque;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * Manages transactions at the Context Hub Service.
@@ -326,10 +312,10 @@
                     mReliableMessageTransactionMap.entrySet().iterator();
             while (iter.hasNext()) {
                 ContextHubServiceTransaction transaction = iter.next().getValue();
-                short hostEndpointId = transaction.getHostEndpointId();
+                long ownerId = transaction.getOwnerId();
                 int numCompletedStartCalls = transaction.getNumCompletedStartCalls();
                 if (numCompletedStartCalls == 0
-                        && mReliableMessageHostEndpointIdActiveSet.contains(hostEndpointId)) {
+                        && mReliableMessageOwnerIdActiveSet.contains(ownerId)) {
                     continue;
                 }
 
@@ -394,7 +380,7 @@
         } else {
             iter.remove();
         }
-        mReliableMessageHostEndpointIdActiveSet.remove(transaction.getHostEndpointId());
+        mReliableMessageOwnerIdActiveSet.remove(transaction.getOwnerId());
 
         Log.d(
                 TAG,
@@ -436,7 +422,7 @@
             transaction.setTimeoutTime(now + RELIABLE_MESSAGE_TIMEOUT.toNanos());
         }
         transaction.setNumCompletedStartCalls(numCompletedStartCalls + 1);
-        mReliableMessageHostEndpointIdActiveSet.add(transaction.getHostEndpointId());
+        mReliableMessageOwnerIdActiveSet.add(transaction.getOwnerId());
     }
 
     @Override
diff --git a/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java b/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java
index b912492..6f5f191 100644
--- a/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java
+++ b/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java
@@ -18,7 +18,9 @@
 
 import android.hardware.contexthub.HubEndpointInfo;
 import android.hardware.contexthub.HubServiceInfo;
+import android.hardware.contexthub.IContextHubEndpointDiscoveryCallback;
 import android.hardware.location.HubInfo;
+import android.os.DeadObjectException;
 import android.os.RemoteException;
 import android.util.ArrayMap;
 import android.util.IndentingPrintWriter;
@@ -29,6 +31,9 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.BiConsumer;
 
 class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycleCallback {
     private static final String TAG = "HubInfoRegistry";
@@ -43,6 +48,56 @@
     private final ArrayMap<HubEndpointInfo.HubEndpointIdentifier, HubEndpointInfo>
             mHubEndpointInfos = new ArrayMap<>();
 
+    /**
+     * A wrapper class that is used to store arguments to
+     * ContextHubManager.registerEndpointCallback.
+     */
+    private static class DiscoveryCallback {
+        private final IContextHubEndpointDiscoveryCallback mCallback;
+        private final Optional<Long> mEndpointId;
+        private final Optional<String> mServiceDescriptor;
+
+        DiscoveryCallback(IContextHubEndpointDiscoveryCallback callback, long endpointId) {
+            mCallback = callback;
+            mEndpointId = Optional.of(endpointId);
+            mServiceDescriptor = Optional.empty();
+        }
+
+        DiscoveryCallback(IContextHubEndpointDiscoveryCallback callback, String serviceDescriptor) {
+            mCallback = callback;
+            mEndpointId = Optional.empty();
+            mServiceDescriptor = Optional.of(serviceDescriptor);
+        }
+
+        public IContextHubEndpointDiscoveryCallback getCallback() {
+            return mCallback;
+        }
+
+        /**
+         * @param info The hub endpoint info to check
+         * @return true if info matches
+         */
+        public boolean isMatch(HubEndpointInfo info) {
+            if (mEndpointId.isPresent()) {
+                return mEndpointId.get() == info.getIdentifier().getEndpoint();
+            }
+            if (mServiceDescriptor.isPresent()) {
+                for (HubServiceInfo serviceInfo : info.getServiceInfoCollection()) {
+                    if (mServiceDescriptor.get().equals(serviceInfo.getServiceDescriptor())) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    /* The list of discovery callbacks registered with the service */
+    @GuardedBy("mCallbackLock")
+    private final List<DiscoveryCallback> mEndpointDiscoveryCallbacks = new ArrayList<>();
+
+    private final Object mCallbackLock = new Object();
+
     HubInfoRegistry(IContextHubWrapper contextHubWrapper) {
         mContextHubWrapper = contextHubWrapper;
         refreshCachedHubs();
@@ -109,16 +164,50 @@
                 mHubEndpointInfos.put(endpointInfo.getIdentifier(), endpointInfo);
             }
         }
+
+        invokeForMatchingEndpoints(
+                endpointInfos,
+                (cb, infoList) -> {
+                    try {
+                        cb.onEndpointsStarted(infoList);
+                    } catch (RemoteException e) {
+                        if (e instanceof DeadObjectException) {
+                            Log.w(TAG, "onEndpointStarted: callback died, unregistering");
+                            unregisterEndpointDiscoveryCallback(cb);
+                        } else {
+                            Log.e(TAG, "Exception while calling onEndpointsStarted", e);
+                        }
+                    }
+                });
     }
 
     @Override
     public void onEndpointStopped(
             HubEndpointInfo.HubEndpointIdentifier[] endpointIds, byte reason) {
+        ArrayList<HubEndpointInfo> removedInfoList = new ArrayList<>();
         synchronized (mLock) {
             for (HubEndpointInfo.HubEndpointIdentifier endpointId : endpointIds) {
-                mHubEndpointInfos.remove(endpointId);
+                HubEndpointInfo info = mHubEndpointInfos.remove(endpointId);
+                if (info != null) {
+                    removedInfoList.add(info);
+                }
             }
         }
+
+        invokeForMatchingEndpoints(
+                removedInfoList.toArray(new HubEndpointInfo[removedInfoList.size()]),
+                (cb, infoList) -> {
+                    try {
+                        cb.onEndpointsStopped(infoList, reason);
+                    } catch (RemoteException e) {
+                        if (e instanceof DeadObjectException) {
+                            Log.w(TAG, "onEndpointStopped: callback died, unregistering");
+                            unregisterEndpointDiscoveryCallback(cb);
+                        } else {
+                            Log.e(TAG, "Exception while calling onEndpointsStopped", e);
+                        }
+                    }
+                });
     }
 
     /** Return a list of {@link HubEndpointInfo} that represents endpoints with the matching id. */
@@ -151,6 +240,77 @@
         return searchResult;
     }
 
+    /* package */
+    void registerEndpointDiscoveryCallback(
+            long endpointId, IContextHubEndpointDiscoveryCallback callback) {
+        Objects.requireNonNull(callback, "callback cannot be null");
+        synchronized (mCallbackLock) {
+            checkCallbackAlreadyRegistered(callback);
+            mEndpointDiscoveryCallbacks.add(new DiscoveryCallback(callback, endpointId));
+        }
+    }
+
+    /* package */
+    void registerEndpointDiscoveryCallback(
+            String serviceDescriptor, IContextHubEndpointDiscoveryCallback callback) {
+        Objects.requireNonNull(callback, "callback cannot be null");
+        synchronized (mCallbackLock) {
+            checkCallbackAlreadyRegistered(callback);
+            mEndpointDiscoveryCallbacks.add(new DiscoveryCallback(callback, serviceDescriptor));
+        }
+    }
+
+    /* package */
+    void unregisterEndpointDiscoveryCallback(IContextHubEndpointDiscoveryCallback callback) {
+        Objects.requireNonNull(callback, "callback cannot be null");
+        synchronized (mCallbackLock) {
+            for (DiscoveryCallback discoveryCallback : mEndpointDiscoveryCallbacks) {
+                if (discoveryCallback.getCallback().asBinder() == callback.asBinder()) {
+                    mEndpointDiscoveryCallbacks.remove(discoveryCallback);
+                    break;
+                }
+            }
+        }
+    }
+
+    private void checkCallbackAlreadyRegistered(
+            IContextHubEndpointDiscoveryCallback callback) {
+        synchronized (mCallbackLock) {
+            for (DiscoveryCallback discoveryCallback : mEndpointDiscoveryCallbacks) {
+                if (discoveryCallback.mCallback.asBinder() == callback.asBinder()) {
+                    throw new IllegalArgumentException("Callback is already registered");
+                }
+            }
+        }
+    }
+
+    /**
+     * Iterates through all registered discovery callbacks and invokes a given callback for those
+     * that match the endpoints the callback is targeted for.
+     *
+     * @param endpointInfos The list of endpoint infos to check for a match.
+     * @param consumer The callback to invoke, which consumes the callback object and the list of
+     *     matched endpoint infos.
+     */
+    private void invokeForMatchingEndpoints(
+            HubEndpointInfo[] endpointInfos,
+            BiConsumer<IContextHubEndpointDiscoveryCallback, HubEndpointInfo[]> consumer) {
+        synchronized (mCallbackLock) {
+            for (DiscoveryCallback discoveryCallback : mEndpointDiscoveryCallbacks) {
+                ArrayList<HubEndpointInfo> infoList = new ArrayList<>();
+                for (HubEndpointInfo endpointInfo : endpointInfos) {
+                    if (discoveryCallback.isMatch(endpointInfo)) {
+                        infoList.add(endpointInfo);
+                    }
+                }
+
+                consumer.accept(
+                        discoveryCallback.getCallback(),
+                        infoList.toArray(new HubEndpointInfo[infoList.size()]));
+            }
+        }
+    }
+
     void dump(IndentingPrintWriter ipw) {
         synchronized (mLock) {
             dumpLocked(ipw);
diff --git a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
index 6cb9429..e1df503 100644
--- a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
+++ b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
@@ -21,6 +21,7 @@
 import android.hardware.contexthub.EndpointId;
 import android.hardware.contexthub.HostEndpointInfo;
 import android.hardware.contexthub.HubEndpointInfo;
+import android.hardware.contexthub.Message;
 import android.hardware.contexthub.MessageDeliveryStatus;
 import android.hardware.contexthub.NanSessionRequest;
 import android.hardware.contexthub.V1_0.ContextHub;
@@ -264,6 +265,13 @@
     /** Notifies the completion of a session opened by the HAL */
     public void endpointSessionOpenComplete(int sessionId) throws RemoteException {}
 
+    /** Sends a message to a remote endpoint */
+    public void sendMessageToEndpoint(int sessionId, Message msg) throws RemoteException {}
+
+    /** Sends a message delivery status to a remote endpoint */
+    public void sendMessageDeliveryStatusToEndpoint(int sessionId, MessageDeliveryStatus msgStatus)
+            throws RemoteException {}
+
     /**
      * @return True if this version of the Contexthub HAL supports Location setting notifications.
      */
@@ -757,6 +765,25 @@
             hub.endpointSessionOpenComplete(sessionId);
         }
 
+        @Override
+        public void sendMessageToEndpoint(int sessionId, Message msg) throws RemoteException {
+            android.hardware.contexthub.IContextHub hub = getHub();
+            if (hub == null) {
+                return;
+            }
+            hub.sendMessageToEndpoint(sessionId, msg);
+        }
+
+        @Override
+        public void sendMessageDeliveryStatusToEndpoint(
+                int sessionId, MessageDeliveryStatus msgStatus) throws RemoteException {
+            android.hardware.contexthub.IContextHub hub = getHub();
+            if (hub == null) {
+                return;
+            }
+            hub.sendMessageDeliveryStatusToEndpoint(sessionId, msgStatus);
+        }
+
         public boolean supportsLocationSettingNotifications() {
             return true;
         }
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
index db1e6b4..d8c3535 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
@@ -66,6 +66,7 @@
     private final int mUserId;
     private final Handler mHandler;
     private final boolean mIsSelfScanOnlyProvider;
+    private final boolean mSupportsSystemMediaRouting;
     private final ServiceConnection mServiceConnection = new ServiceConnectionImpl();
 
     // Connection state
@@ -95,12 +96,14 @@
             @NonNull Looper looper,
             @NonNull ComponentName componentName,
             boolean isSelfScanOnlyProvider,
+            boolean supportsSystemMediaRouting,
             int userId) {
         super(componentName, /* isSystemRouteProvider= */ false);
         mContext = Objects.requireNonNull(context, "Context must not be null.");
         mRequestIdToSessionCreationRequest = new LongSparseArray<>();
         mSessionOriginalIdToTransferRequest = new HashMap<>();
         mIsSelfScanOnlyProvider = isSelfScanOnlyProvider;
+        mSupportsSystemMediaRouting = supportsSystemMediaRouting;
         mUserId = userId;
         mHandler = new Handler(looper);
     }
@@ -276,13 +279,20 @@
         if (!mRunning) {
             return false;
         }
+        // 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
+        // b/176774510#comment20 for more information.
         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
-            // b/176774510#comment20 for more information.
+        // We also bind if this provider supports system media routing, because even if an app
+        // doesn't have any registered discovery preference, we should still be able to route their
+        // system media.
+        boolean bindDueToSystemMediaRoutingSupport =
+                mIsManagerScanning && mSupportsSystemMediaRouting;
+        if (!getSessionInfos().isEmpty()
+                || bindDueToManagerScan
+                || bindDueToSystemMediaRoutingSupport) {
             return true;
         }
         boolean anAppIsScanning =
@@ -651,11 +661,12 @@
         }
         return TextUtils.formatSimple(
                 "ProviderServiceProxy - package: %s, bound: %b, connection (active:%b, ready:%b), "
-                        + "pending (session creations: %d, transfers: %d)",
+                        + "system media=%b, pending (session creations: %d, transfers: %d)",
                 mComponentName.getPackageName(),
                 mBound,
                 mActiveConnection != null,
                 mConnectionReady,
+                mSupportsSystemMediaRouting,
                 pendingSessionCreationCount,
                 pendingTransferCount);
     }
@@ -697,7 +708,7 @@
 
         Connection(IMediaRoute2ProviderService serviceBinder) {
             mService = serviceBinder;
-            mCallbackStub = new ServiceCallbackStub(this);
+            mCallbackStub = new ServiceCallbackStub(this, mSupportsSystemMediaRouting);
         }
 
         public boolean register() {
@@ -811,9 +822,11 @@
     private static final class ServiceCallbackStub extends
             IMediaRoute2ProviderServiceCallback.Stub {
         private final WeakReference<Connection> mConnectionRef;
+        private final boolean mAllowSystemMediaRoutes;
 
-        ServiceCallbackStub(Connection connection) {
+        ServiceCallbackStub(Connection connection, boolean allowSystemMediaRoutes) {
             mConnectionRef = new WeakReference<>(connection);
+            mAllowSystemMediaRoutes = allowSystemMediaRoutes;
         }
 
         public void dispose() {
@@ -846,6 +859,13 @@
                                     + "Disallowed route: "
                                     + route);
                 }
+
+                if (route.supportsSystemMediaRouting() && !mAllowSystemMediaRoutes) {
+                    throw new SecurityException(
+                            "This provider is not allowed to publish routes that support system"
+                                    + " media routing. Disallowed route: "
+                                    + route);
+                }
             }
 
             Connection connection = mConnectionRef.get();
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
index 93ef6f0..69c460e 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
@@ -17,7 +17,9 @@
 package com.android.server.media;
 
 import static android.content.pm.PackageManager.GET_RESOLVED_FILTER;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 
+import android.Manifest;
 import android.annotation.NonNull;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -130,22 +132,33 @@
             ServiceInfo serviceInfo = resolveInfo.serviceInfo;
             if (serviceInfo != null) {
                 boolean isSelfScanOnlyProvider = false;
+                boolean supportsSystemMediaRouting = false;
                 Iterator<String> categoriesIterator = resolveInfo.filter.categoriesIterator();
                 if (categoriesIterator != null) {
                     while (categoriesIterator.hasNext()) {
+                        String category = categoriesIterator.next();
                         isSelfScanOnlyProvider |=
-                                MediaRoute2ProviderService.CATEGORY_SELF_SCAN_ONLY.equals(
-                                        categoriesIterator.next());
+                                MediaRoute2ProviderService.CATEGORY_SELF_SCAN_ONLY.equals(category);
+                        supportsSystemMediaRouting |=
+                                MediaRoute2ProviderService.SERVICE_INTERFACE_SYSTEM_MEDIA.equals(
+                                        category);
                     }
                 }
                 int sourceIndex = findProvider(serviceInfo.packageName, serviceInfo.name);
                 if (sourceIndex < 0) {
+                    supportsSystemMediaRouting &= Flags.enableMirroringInMediaRouter2();
+                    supportsSystemMediaRouting &=
+                            mPackageManager.checkPermission(
+                                            Manifest.permission.MODIFY_AUDIO_ROUTING,
+                                            serviceInfo.packageName)
+                                    == PERMISSION_GRANTED;
                     MediaRoute2ProviderServiceProxy proxy =
                             new MediaRoute2ProviderServiceProxy(
                                     mContext,
                                     mHandler.getLooper(),
                                     new ComponentName(serviceInfo.packageName, serviceInfo.name),
                                     isSelfScanOnlyProvider,
+                                    supportsSystemMediaRouting,
                                     mUserId);
                     Slog.i(
                             TAG,
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index abc067d..e18ed41 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -2581,9 +2581,9 @@
             mUserRecord = userRecord;
             mSystemProvider =
                     Flags.enableMirroringInMediaRouter2()
-                            ? new SystemMediaRoute2Provider2(
+                            ? SystemMediaRoute2Provider2.create(
                                     service.mContext, UserHandle.of(userRecord.mUserId), looper)
-                            : new SystemMediaRoute2Provider(
+                            : SystemMediaRoute2Provider.create(
                                     service.mContext, UserHandle.of(userRecord.mUserId), looper);
             mRouteProviders.add(getSystemProvider());
             mWatcher = new MediaRoute2ProviderWatcher(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 5fb80ba..8dfba39 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -89,8 +89,12 @@
     @Nullable
     private volatile SessionCreationOrTransferRequest mPendingTransferRequest;
 
-    SystemMediaRoute2Provider(Context context, UserHandle user, Looper looper) {
-        this(context, COMPONENT_NAME, user, looper);
+    public static SystemMediaRoute2Provider create(
+            Context context, UserHandle user, Looper looper) {
+        var instance = new SystemMediaRoute2Provider(context, COMPONENT_NAME, user, looper);
+        instance.updateProviderState();
+        instance.updateSessionInfosIfNeeded();
+        return instance;
     }
 
     protected SystemMediaRoute2Provider(
@@ -124,8 +128,6 @@
                                                 notifySessionInfoUpdated();
                                             }
                                         }));
-        updateProviderState();
-        updateSessionInfosIfNeeded();
     }
 
     public void start() {
@@ -362,7 +364,7 @@
         }
     }
 
-    private void updateProviderState() {
+    protected void updateProviderState() {
         MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder();
 
         // We must have a device route in the provider info.
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java
index 8a14a38..85b30ad 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java
@@ -35,7 +35,15 @@
                     SystemMediaRoute2Provider2.class.getPackage().getName(),
                     SystemMediaRoute2Provider2.class.getName());
 
-    SystemMediaRoute2Provider2(Context context, UserHandle user, Looper looper) {
+    public static SystemMediaRoute2Provider2 create(
+            Context context, UserHandle user, Looper looper) {
+        var instance = new SystemMediaRoute2Provider2(context, user, looper);
+        instance.updateProviderState();
+        instance.updateSessionInfosIfNeeded();
+        return instance;
+    }
+
+    private SystemMediaRoute2Provider2(Context context, UserHandle user, Looper looper) {
         super(context, COMPONENT_NAME, user, looper);
     }
 }
diff --git a/services/core/java/com/android/server/media/quality/BiMap.java b/services/core/java/com/android/server/media/quality/BiMap.java
new file mode 100644
index 0000000..82b8284
--- /dev/null
+++ b/services/core/java/com/android/server/media/quality/BiMap.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media.quality;
+
+import android.util.ArrayMap;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * A very basic bidirectional map.
+ *
+ * @param <K> data type of Key
+ * @param <V> data type of Value
+ */
+public class BiMap<K, V> {
+    private Map<K, V> mPrimaryMap = new ArrayMap<>();
+    private Map<V, K> mSecondaryMap = new ArrayMap<>();
+
+    /**
+     * Add key and associated value to the map
+     *
+     * @param key key to add
+     * @param value value to add
+     * @return true if successfully added, false otherwise
+     */
+    public boolean put(K key, V value) {
+        if (key == null || value == null || mPrimaryMap.containsKey(key)
+                || mSecondaryMap.containsKey(value)) {
+            return false;
+        }
+
+        mPrimaryMap.put(key, value);
+        mSecondaryMap.put(value, key);
+        return true;
+    }
+
+    /**
+     * Remove key and associated value from the map
+     *
+     * @param key key to remove
+     * @return true if removed, false otherwise
+     */
+    public boolean remove(K key) {
+        if (key == null) {
+            return false;
+        }
+        if (mPrimaryMap.containsKey(key)) {
+            V value = getValue(key);
+            mPrimaryMap.remove(key);
+            mSecondaryMap.remove(value);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Remove value and associated key from the map
+     *
+     * @param value value to remove
+     * @return true if removed, false otherwise
+     */
+    public boolean removeValue(V value) {
+        if (value == null) {
+            return false;
+        }
+        return remove(getKey(value));
+    }
+
+    /**
+     * Get the value
+     *
+     * @param key key for which to get value
+     * @return V
+     */
+    public V getValue(K key) {
+        return mPrimaryMap.get(key);
+    }
+
+    /**
+     * Get the key
+     *
+     * @param value value for which to get key
+     * @return K
+     */
+    public K getKey(V value) {
+        return mSecondaryMap.get(value);
+    }
+
+    /**
+     * Get the values of the map.
+     * @return Collection
+     */
+    public Collection<V> getValues() {
+        return mPrimaryMap.values();
+    }
+
+    /**
+     * Clear the map
+     */
+    public void clear() {
+        mPrimaryMap.clear();
+        mSecondaryMap.clear();
+    }
+}
diff --git a/services/core/java/com/android/server/media/quality/MediaQualityService.java b/services/core/java/com/android/server/media/quality/MediaQualityService.java
index 1673b8e..3e488bf 100644
--- a/services/core/java/com/android/server/media/quality/MediaQualityService.java
+++ b/services/core/java/com/android/server/media/quality/MediaQualityService.java
@@ -31,15 +31,13 @@
 import android.media.quality.PictureProfileHandle;
 import android.media.quality.SoundProfile;
 import android.media.quality.SoundProfileHandle;
+import android.os.Binder;
 import android.os.PersistableBundle;
 import android.os.UserHandle;
 import android.util.Log;
 
 import com.android.server.SystemService;
 
-import com.google.common.collect.BiMap;
-import com.google.common.collect.HashBiMap;
-
 import org.json.JSONException;
 import org.json.JSONObject;
 
@@ -58,6 +56,7 @@
 
     private static final boolean DEBUG = false;
     private static final String TAG = "MediaQualityService";
+    private static final int MAX_UUID_GENERATION_ATTEMPTS = 10;
     private final Context mContext;
     private final MediaQualityDbHelper mMediaQualityDbHelper;
     private final BiMap<Long, String> mPictureProfileTempIdMap;
@@ -66,8 +65,8 @@
     public MediaQualityService(Context context) {
         super(context);
         mContext = context;
-        mPictureProfileTempIdMap = HashBiMap.create();
-        mSoundProfileTempIdMap = HashBiMap.create();
+        mPictureProfileTempIdMap = new BiMap<>();
+        mSoundProfileTempIdMap = new BiMap<>();
         mMediaQualityDbHelper = new MediaQualityDbHelper(mContext);
         mMediaQualityDbHelper.setWriteAheadLoggingEnabled(true);
         mMediaQualityDbHelper.setIdleConnectionTimeout(30);
@@ -85,29 +84,40 @@
         public PictureProfile createPictureProfile(PictureProfile pp, UserHandle user) {
             SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase();
 
-            ContentValues values = new ContentValues();
-            values.put(BaseParameters.PARAMETER_TYPE, pp.getProfileType());
-            values.put(BaseParameters.PARAMETER_NAME, pp.getName());
-            values.put(BaseParameters.PARAMETER_PACKAGE, pp.getPackageName());
-            values.put(BaseParameters.PARAMETER_INPUT_ID, pp.getInputId());
-            values.put(mMediaQualityDbHelper.SETTINGS, persistableBundleToJson(pp.getParameters()));
+            ContentValues values = getContentValues(null,
+                    pp.getProfileType(),
+                    pp.getName(),
+                    pp.getPackageName(),
+                    pp.getInputId(),
+                    pp.getParameters());
 
             // id is auto-generated by SQLite upon successful insertion of row
             Long id = db.insert(mMediaQualityDbHelper.PICTURE_QUALITY_TABLE_NAME,
                     null, values);
             populateTempIdMap(mPictureProfileTempIdMap, id);
-            pp.setProfileId(mPictureProfileTempIdMap.get(id));
+            pp.setProfileId(mPictureProfileTempIdMap.getValue(id));
             return pp;
         }
 
         @Override
         public void updatePictureProfile(String id, PictureProfile pp, UserHandle user) {
-            // TODO: implement
+            Long intId = mPictureProfileTempIdMap.getKey(id);
+
+            ContentValues values = getContentValues(intId,
+                    pp.getProfileType(),
+                    pp.getName(),
+                    pp.getPackageName(),
+                    pp.getInputId(),
+                    pp.getParameters());
+
+            SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase();
+            db.replace(mMediaQualityDbHelper.PICTURE_QUALITY_TABLE_NAME,
+                    null, values);
         }
 
         @Override
         public void removePictureProfile(String id, UserHandle user) {
-            Long intId = mPictureProfileTempIdMap.inverse().get(id);
+            Long intId = mPictureProfileTempIdMap.getKey(id);
             if (intId != null) {
                 SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase();
                 String selection = BaseParameters.PARAMETER_ID + " = ?";
@@ -157,6 +167,11 @@
         @Override
         public List<PictureProfile> getAvailablePictureProfiles(
                 boolean includeParams, UserHandle user) {
+            String[] packageNames = mContext.getPackageManager().getPackagesForUid(
+                    Binder.getCallingUid());
+            if (packageNames != null && packageNames.length == 1 && !packageNames[0].isEmpty()) {
+                return getPictureProfilesByPackage(packageNames[0], includeParams, user);
+            }
             return new ArrayList<>();
         }
 
@@ -191,29 +206,39 @@
         public SoundProfile createSoundProfile(SoundProfile sp, UserHandle user) {
             SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase();
 
-            ContentValues values = new ContentValues();
-            values.put(BaseParameters.PARAMETER_TYPE, sp.getProfileType());
-            values.put(BaseParameters.PARAMETER_NAME, sp.getName());
-            values.put(BaseParameters.PARAMETER_PACKAGE, sp.getPackageName());
-            values.put(BaseParameters.PARAMETER_INPUT_ID, sp.getInputId());
-            values.put(mMediaQualityDbHelper.SETTINGS, persistableBundleToJson(sp.getParameters()));
+            ContentValues values = getContentValues(null,
+                    sp.getProfileType(),
+                    sp.getName(),
+                    sp.getPackageName(),
+                    sp.getInputId(),
+                    sp.getParameters());
 
             // id is auto-generated by SQLite upon successful insertion of row
             Long id = db.insert(mMediaQualityDbHelper.SOUND_QUALITY_TABLE_NAME,
                     null, values);
             populateTempIdMap(mSoundProfileTempIdMap, id);
-            sp.setProfileId(mSoundProfileTempIdMap.get(id));
+            sp.setProfileId(mSoundProfileTempIdMap.getValue(id));
             return sp;
         }
 
         @Override
-        public void updateSoundProfile(String id, SoundProfile pp, UserHandle user) {
-            // TODO: implement
+        public void updateSoundProfile(String id, SoundProfile sp, UserHandle user) {
+            Long intId = mSoundProfileTempIdMap.getKey(id);
+
+            ContentValues values = getContentValues(intId,
+                    sp.getProfileType(),
+                    sp.getName(),
+                    sp.getPackageName(),
+                    sp.getInputId(),
+                    sp.getParameters());
+
+            SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase();
+            db.replace(mMediaQualityDbHelper.SOUND_QUALITY_TABLE_NAME, null, values);
         }
 
         @Override
         public void removeSoundProfile(String id, UserHandle user) {
-            Long intId = mSoundProfileTempIdMap.inverse().get(id);
+            Long intId = mSoundProfileTempIdMap.getKey(id);
             if (intId != null) {
                 SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase();
                 String selection = BaseParameters.PARAMETER_ID + " = ?";
@@ -263,6 +288,11 @@
         @Override
         public List<SoundProfile> getAvailableSoundProfiles(
                 boolean includeParams, UserHandle user) {
+            String[] packageNames = mContext.getPackageManager().getPackagesForUid(
+                    Binder.getCallingUid());
+            if (packageNames != null && packageNames.length == 1 && !packageNames[0].isEmpty()) {
+                return getSoundProfilesByPackage(packageNames[0], includeParams, user);
+            }
             return new ArrayList<>();
         }
 
@@ -284,12 +314,17 @@
         }
 
         private void populateTempIdMap(BiMap<Long, String> map, Long id) {
-            if (id != null && map.get(id) == null) {
-                String uuid = UUID.randomUUID().toString();
-                while (map.inverse().containsKey(uuid)) {
+            if (id != null && map.getValue(id) == null) {
+                String uuid;
+                int attempts = 0;
+                while (attempts < MAX_UUID_GENERATION_ATTEMPTS) {
                     uuid = UUID.randomUUID().toString();
+                    if (map.getKey(uuid) == null) {
+                        map.put(id, uuid);
+                        return;
+                    }
+                    attempts++;
                 }
-                map.put(id, uuid);
             }
         }
 
@@ -316,7 +351,7 @@
             return json.toString();
         }
 
-        private PersistableBundle jsonToBundle(String jsonString) {
+        private PersistableBundle jsonToPersistableBundle(String jsonString) {
             PersistableBundle bundle = new PersistableBundle();
             if (jsonString != null) {
                 JSONObject jsonObject = null;
@@ -347,6 +382,30 @@
             return bundle;
         }
 
+        private ContentValues getContentValues(Long dbId, Integer profileType, String name,
+                String packageName, String inputId, PersistableBundle params) {
+            ContentValues values = new ContentValues();
+            if (dbId != null) {
+                values.put(BaseParameters.PARAMETER_ID, dbId);
+            }
+            if (profileType != null) {
+                values.put(BaseParameters.PARAMETER_TYPE, profileType);
+            }
+            if (name != null) {
+                values.put(BaseParameters.PARAMETER_NAME, name);
+            }
+            if (packageName != null) {
+                values.put(BaseParameters.PARAMETER_PACKAGE, packageName);
+            }
+            if (inputId != null) {
+                values.put(BaseParameters.PARAMETER_INPUT_ID, inputId);
+            }
+            if (params != null) {
+                values.put(mMediaQualityDbHelper.SETTINGS, persistableBundleToJson(params));
+            }
+            return values;
+        }
+
         private String[] getAllMediaProfileColumns() {
             return new String[]{
                     BaseParameters.PARAMETER_ID,
@@ -365,7 +424,7 @@
                     getName(cursor),
                     getInputId(cursor),
                     getPackageName(cursor),
-                    jsonToBundle(getSettingsString(cursor)),
+                    jsonToPersistableBundle(getSettingsString(cursor)),
                     PictureProfileHandle.NONE
             );
         }
@@ -377,7 +436,7 @@
                     getName(cursor),
                     getInputId(cursor),
                     getPackageName(cursor),
-                    jsonToBundle(getSettingsString(cursor)),
+                    jsonToPersistableBundle(getSettingsString(cursor)),
                     SoundProfileHandle.NONE
             );
         }
@@ -386,7 +445,7 @@
             int colIndex = cursor.getColumnIndex(BaseParameters.PARAMETER_ID);
             Long dbId = colIndex != -1 ? cursor.getLong(colIndex) : null;
             populateTempIdMap(map, dbId);
-            return map.get(dbId);
+            return map.getValue(dbId);
         }
 
         private int getType(Cursor cursor) {
diff --git a/services/core/java/com/android/server/media/quality/OWNERS b/services/core/java/com/android/server/media/quality/OWNERS
index e455846..7171aa4 100644
--- a/services/core/java/com/android/server/media/quality/OWNERS
+++ b/services/core/java/com/android/server/media/quality/OWNERS
@@ -1,2 +1,3 @@
 shubang@google.com
-haofanw@google.com
\ No newline at end of file
+haofanw@google.com
+pkandhalu@google.com
\ No newline at end of file
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 39eea74..504c298 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -361,6 +361,7 @@
 import com.android.server.notification.GroupHelper.NotificationAttributes;
 import com.android.server.notification.ManagedServices.ManagedServiceInfo;
 import com.android.server.notification.ManagedServices.UserProfiles;
+import com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent;
 import com.android.server.notification.toast.CustomToastRecord;
 import com.android.server.notification.toast.TextToastRecord;
 import com.android.server.notification.toast.ToastRecord;
@@ -1934,10 +1935,20 @@
                 hasSensitiveContent, lifespanMs);
     }
 
-    protected void logClassificationChannelAdjustmentReceived(boolean hasPosted, boolean isAlerting,
-                                                              int classification, int lifespanMs) {
+    protected void logClassificationChannelAdjustmentReceived(NotificationRecord r,
+                                                              boolean hasPosted,
+                                                              int classification) {
+        // Note that this value of isAlerting does not fully indicate whether a notif
+        // would make a sound or HUN on device; it is an approximation for metrics.
+        boolean isAlerting = r.getChannel().getImportance() >= IMPORTANCE_DEFAULT;
+        int instanceId = r.getSbn().getInstanceId() == null
+                ? 0 : r.getSbn().getInstanceId().getId();
+
         FrameworkStatsLog.write(FrameworkStatsLog.NOTIFICATION_CHANNEL_CLASSIFICATION,
-                hasPosted, isAlerting, classification, lifespanMs);
+                hasPosted, isAlerting, classification,
+                r.getLifespanMs(System.currentTimeMillis()),
+                NotificationReportedEvent.NOTIFICATION_ADJUSTED.getId(),
+                instanceId, r.getUid());
     }
 
     protected final BroadcastReceiver mLocaleChangeReceiver = new BroadcastReceiver() {
@@ -7052,11 +7063,8 @@
                     int classification = adjustments.getInt(KEY_TYPE);
                     // swap app provided type with the real thing
                     adjustments.putParcelable(KEY_TYPE, newChannel);
-                    // Note that this value of isAlerting does not fully indicate whether a notif
-                    // would make a sound or HUN on device; it is an approximation for metrics.
-                    boolean isAlerting = r.getChannel().getImportance() >= IMPORTANCE_DEFAULT;
-                    logClassificationChannelAdjustmentReceived(isPosted, isAlerting, classification,
-                            r.getLifespanMs(System.currentTimeMillis()));
+
+                    logClassificationChannelAdjustmentReceived(r, isPosted, classification);
                 }
             }
             r.addAdjustment(adjustment);
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index c09077e..f17ac5c 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -21,6 +21,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.SystemClock;
+import android.service.notification.RateEstimator;
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
diff --git a/services/core/java/com/android/server/pm/BroadcastHelper.java b/services/core/java/com/android/server/pm/BroadcastHelper.java
index 6d54be8..676c6fa 100644
--- a/services/core/java/com/android/server/pm/BroadcastHelper.java
+++ b/services/core/java/com/android/server/pm/BroadcastHelper.java
@@ -53,6 +53,7 @@
 import android.os.PowerExemptionManager;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
@@ -78,6 +79,7 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.function.BiFunction;
+import java.util.function.Supplier;
 
 /**
  * Helper class to send broadcasts for various situations.
@@ -216,7 +218,7 @@
                 filterExtrasForReceiver, bOptions);
     }
 
-    void sendResourcesChangedBroadcast(@NonNull Computer snapshot,
+    void sendResourcesChangedBroadcast(@NonNull Supplier<Computer> snapshotSupplier,
                                        boolean mediaStatus,
                                        boolean replacing,
                                        @NonNull String[] pkgNames,
@@ -236,7 +238,7 @@
                 null /* targetPkg */, null /* finishedReceiver */, null /* userIds */,
                 null /* instantUserIds */, null /* broadcastAllowList */,
                 (callingUid, intentExtras) -> filterExtrasChangedPackageList(
-                        snapshot, callingUid, intentExtras),
+                        snapshotSupplier, callingUid, intentExtras),
                 null /* bOptions */, null /* requiredPermissions */);
     }
 
@@ -357,9 +359,14 @@
             @Nullable int[] instantUserIds,
             @Nullable SparseArray<int[]> broadcastAllowList,
             @NonNull AndroidPackage pkg,
-            @NonNull String[] sharedUidPackages) {
+            @NonNull String[] sharedUidPackages,
+            @NonNull String reasonForTrace) {
         final boolean isForWholeApp = componentNames.contains(packageName);
         if (isForWholeApp || !android.content.pm.Flags.reduceBroadcastsForComponentStateChanges()) {
+            tracePackageChangedBroadcastEvent(
+                    android.content.pm.Flags.reduceBroadcastsForComponentStateChanges(),
+                    reasonForTrace, packageName, "<implicit>" /* targetPackageName */,
+                    "whole" /* targetComponent */, componentNames.size());
             sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp, componentNames,
                     packageUid, reason, userIds, instantUserIds, broadcastAllowList,
                     null /* targetPackageName */, null /* requiredPermissions */);
@@ -381,6 +388,9 @@
 
             // First, send the PACKAGE_CHANGED broadcast to the system.
             if (!TextUtils.equals(packageName, "android")) {
+                tracePackageChangedBroadcastEvent(true /* applyFlag */, reasonForTrace, packageName,
+                        "android" /* targetPackageName */, "notExported" /* targetComponent */,
+                        notExportedComponentNames.size());
                 sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp,
                         notExportedComponentNames, packageUid, reason, userIds, instantUserIds,
                         broadcastAllowList, "android" /* targetPackageName */,
@@ -389,6 +399,9 @@
             }
 
             // Second, send the PACKAGE_CHANGED broadcast to the application itself.
+            tracePackageChangedBroadcastEvent(true /* applyFlag */, reasonForTrace, packageName,
+                    packageName /* targetPackageName */, "notExported" /* targetComponent */,
+                    notExportedComponentNames.size());
             sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp,
                     notExportedComponentNames, packageUid, reason, userIds, instantUserIds,
                     broadcastAllowList, packageName /* targetPackageName */,
@@ -400,6 +413,9 @@
                 if (TextUtils.equals(packageName, sharedPackage)) {
                     continue;
                 }
+                tracePackageChangedBroadcastEvent(true /* applyFlag */, reasonForTrace, packageName,
+                        sharedPackage /* targetPackageName */, "notExported" /* targetComponent */,
+                        notExportedComponentNames.size());
                 sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp,
                         notExportedComponentNames, packageUid, reason, userIds, instantUserIds,
                         broadcastAllowList, sharedPackage /* targetPackageName */,
@@ -409,6 +425,9 @@
         }
 
         if (!exportedComponentNames.isEmpty()) {
+            tracePackageChangedBroadcastEvent(true /* applyFlag */, reasonForTrace, packageName,
+                    "<implicit>" /* targetPackageName */, "exported" /* targetComponent */,
+                    exportedComponentNames.size());
             sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp,
                     exportedComponentNames, packageUid, reason, userIds, instantUserIds,
                     broadcastAllowList, null /* targetPackageName */,
@@ -544,7 +563,7 @@
         });
     }
 
-    void sendPostInstallBroadcasts(@NonNull Computer snapshot,
+    void sendPostInstallBroadcasts(@NonNull Supplier<Computer> snapshotSupplier,
                                    @NonNull InstallRequest request,
                                    @NonNull String packageName,
                                    @NonNull String requiredPermissionControllerPackage,
@@ -567,8 +586,8 @@
                 final int[] uids = new int[]{request.getRemovedInfo().mUid};
                 notifyResourcesChanged(
                         false /* mediaStatus */, true /* replacing */, pkgNames, uids);
-                sendResourcesChangedBroadcast(
-                        snapshot, false /* mediaStatus */, true /* replacing */, pkgNames, uids);
+                sendResourcesChangedBroadcast(snapshotSupplier,
+                        false /* mediaStatus */, true /* replacing */, pkgNames, uids);
             }
             sendPackageRemovedBroadcasts(
                     request.getRemovedInfo(), packageSender, isKillApp, false /*removedBySystem*/,
@@ -608,6 +627,7 @@
                     null /* broadcastAllowList */, null);
         }
 
+        final Computer snapshot = snapshotSupplier.get();
         // Send installed broadcasts if the package is not a static shared lib.
         if (staticSharedLibraryName == null) {
             // Send PACKAGE_ADDED broadcast for users that see the package for the first time
@@ -732,7 +752,7 @@
                 if (!isArchived) {
                     final String[] pkgNames = new String[]{packageName};
                     final int[] uids = new int[]{request.getPkg().getUid()};
-                    sendResourcesChangedBroadcast(snapshot,
+                    sendResourcesChangedBroadcast(snapshotSupplier,
                             true /* mediaStatus */, true /* replacing */, pkgNames, uids);
                     notifyResourcesChanged(true /* mediaStatus */,
                             true /* replacing */, pkgNames, uids);
@@ -749,7 +769,8 @@
                     sendPackageChangedBroadcast(snapshot, pkg.getPackageName(),
                             dontKillApp,
                             new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
-                            pkg.getUid(), null);
+                            pkg.getUid(), null /* reason */,
+                            "static_shared_library_changed" /* reasonForTrace */);
                 }
             }
         }
@@ -860,8 +881,8 @@
      * access all the packages in the extras.
      */
     @Nullable
-    private static Bundle filterExtrasChangedPackageList(@NonNull Computer snapshot, int callingUid,
-            @NonNull Bundle extras) {
+    private static Bundle filterExtrasChangedPackageList(
+            @NonNull Supplier<Computer> snapshotSupplier, int callingUid, @NonNull Bundle extras) {
         if (UserHandle.isCore(callingUid)) {
             // see all
             return extras;
@@ -873,6 +894,7 @@
         final int userId = extras.getInt(
                 Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(callingUid));
         final int[] uids = extras.getIntArray(Intent.EXTRA_CHANGED_UID_LIST);
+        final Computer snapshot = snapshotSupplier.get();
         final Pair<String[], int[]> filteredPkgs =
                 filterPackages(snapshot, pkgs, uids, callingUid, userId);
         if (ArrayUtils.isEmpty(filteredPkgs.first)) {
@@ -939,7 +961,8 @@
                                      boolean dontKillApp,
                                      @NonNull ArrayList<String> componentNames,
                                      int packageUid,
-                                     @NonNull String reason) {
+                                     @NonNull String reason,
+                                     @NonNull String reasonForTrace) {
         PackageStateInternal setting = snapshot.getPackageStateInternal(packageName,
                 Process.SYSTEM_UID);
         if (setting == null || setting.getPkg() == null) {
@@ -952,10 +975,12 @@
         final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
         final SparseArray<int[]> broadcastAllowList =
                 isInstantApp ? null : snapshot.getVisibilityAllowLists(packageName, userIds);
+        final String[] sharedUserPackages =
+                snapshot.getSharedUserPackagesForPackage(packageName, userId);
         mHandler.post(() -> sendPackageChangedBroadcastInternal(
                 packageName, dontKillApp, componentNames, packageUid, reason, userIds,
                 instantUserIds, broadcastAllowList, setting.getPkg(),
-                snapshot.getSharedUserPackagesForPackage(packageName, userId)));
+                sharedUserPackages, reasonForTrace));
         mPackageMonitorCallbackHelper.notifyPackageChanged(packageName, dontKillApp, componentNames,
                 packageUid, reason, userIds, instantUserIds, broadcastAllowList, mHandler);
     }
@@ -1120,7 +1145,7 @@
      * @param uidList The uids of packages which have suspension changes.
      * @param userId The user where packages reside.
      */
-    void sendPackagesSuspendedOrUnsuspendedForUser(@NonNull Computer snapshot,
+    void sendPackagesSuspendedOrUnsuspendedForUser(@NonNull Supplier<Computer> snapshotSupplier,
                                                    @NonNull String intent,
                                                    @NonNull String[] pkgList,
                                                    @NonNull int[] uidList,
@@ -1138,7 +1163,7 @@
                 .toBundle();
         BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver =
                 (callingUid, intentExtras) -> BroadcastHelper.filterExtrasChangedPackageList(
-                        snapshot, callingUid, intentExtras);
+                        snapshotSupplier, callingUid, intentExtras);
         mHandler.post(() -> sendPackageBroadcast(intent, null /* pkg */,
                 extras, flags, null /* targetPkg */, null /* finishedReceiver */,
                 new int[]{userId}, null /* instantUserIds */, null /* broadcastAllowList */,
@@ -1148,7 +1173,7 @@
                 null /* instantUserIds */, null /* broadcastAllowList */, filterExtrasForReceiver);
     }
 
-    void sendMyPackageSuspendedOrUnsuspended(@NonNull Computer snapshot,
+    void sendMyPackageSuspendedOrUnsuspended(@NonNull Supplier<Computer> snapshotSupplier,
                                              @NonNull String[] affectedPackages,
                                              boolean suspended,
                                              int userId) {
@@ -1163,6 +1188,7 @@
                 return;
             }
             final int[] targetUserIds = new int[] {userId};
+            final Computer snapshot = snapshotSupplier.get();
             for (String packageName : affectedPackages) {
                 final Bundle appExtras = suspended
                         ? SuspendPackageHelper.getSuspendedPackageAppExtras(
@@ -1192,7 +1218,7 @@
      * @param uidList The uids of packages which have suspension changes.
      * @param userId The user where packages reside.
      */
-    void sendDistractingPackagesChanged(@NonNull Computer snapshot,
+    void sendDistractingPackagesChanged(@NonNull Supplier<Computer> snapshotSupplier,
                                         @NonNull String[] pkgList,
                                         @NonNull int[] uidList,
                                         int userId,
@@ -1208,11 +1234,11 @@
                 null /* finishedReceiver */, new int[]{userId}, null /* instantUserIds */,
                 null /* broadcastAllowList */,
                 (callingUid, intentExtras) -> filterExtrasChangedPackageList(
-                        snapshot, callingUid, intentExtras),
+                        snapshotSupplier, callingUid, intentExtras),
                 null /* bOptions */, null /* requiredPermissions */));
     }
 
-    void sendResourcesChangedBroadcastAndNotify(@NonNull Computer snapshot,
+    void sendResourcesChangedBroadcastAndNotify(@NonNull Supplier<Computer> snapshotSupplier,
                                                 boolean mediaStatus,
                                                 boolean replacing,
                                                 @NonNull ArrayList<AndroidPackage> packages) {
@@ -1224,7 +1250,7 @@
             packageNames[i] = pkg.getPackageName();
             packageUids[i] = pkg.getUid();
         }
-        sendResourcesChangedBroadcast(snapshot, mediaStatus,
+        sendResourcesChangedBroadcast(snapshotSupplier, mediaStatus,
                 replacing, packageNames, packageUids);
         notifyResourcesChanged(mediaStatus, replacing, packageNames, packageUids);
     }
@@ -1247,4 +1273,25 @@
         mPackageMonitorCallbackHelper.notifyResourcesChanged(mediaStatus, replacing, pkgNames,
                 uids, mHandler);
     }
+
+    private static void tracePackageChangedBroadcastEvent(boolean applyFlag,
+            @NonNull String reasonForTrace, @Nullable String packageName,
+            @Nullable String targetPackageName, @Nullable String targetComponent,
+            int componentSize) {
+
+        if (!Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
+            return;
+        }
+
+        final StringBuilder builder = new StringBuilder();
+        builder.append("broadcastPackageChanged; ");
+        builder.append("af="); builder.append(applyFlag);
+        builder.append(",rft="); builder.append(reasonForTrace);
+        builder.append(",pn="); builder.append(packageName);
+        builder.append(",tpn="); builder.append(targetPackageName);
+        builder.append(",tc="); builder.append(targetComponent);
+        builder.append(",cs="); builder.append(componentSize);
+
+        Trace.instant(Trace.TRACE_TAG_SYSTEM_SERVER, builder.toString());
+    }
 }
diff --git a/services/core/java/com/android/server/pm/DistractingPackageHelper.java b/services/core/java/com/android/server/pm/DistractingPackageHelper.java
index c5ec73b..c4e981d 100644
--- a/services/core/java/com/android/server/pm/DistractingPackageHelper.java
+++ b/services/core/java/com/android/server/pm/DistractingPackageHelper.java
@@ -123,7 +123,7 @@
         if (!changedPackagesList.isEmpty()) {
             final String[] changedPackages = changedPackagesList.toArray(
                     new String[changedPackagesList.size()]);
-            mBroadcastHelper.sendDistractingPackagesChanged(mPm.snapshotComputer(),
+            mBroadcastHelper.sendDistractingPackagesChanged(mPm::snapshotComputer,
                     changedPackages, changedUids.toArray(), userId, restrictionFlags);
             mPm.scheduleWritePackageRestrictions(userId);
         }
@@ -198,7 +198,7 @@
         if (!changedPackages.isEmpty()) {
             final String[] packageArray = changedPackages.toArray(
                     new String[changedPackages.size()]);
-            mBroadcastHelper.sendDistractingPackagesChanged(mPm.snapshotComputer(),
+            mBroadcastHelper.sendDistractingPackagesChanged(mPm::snapshotComputer,
                     packageArray, changedUids.toArray(), userId, RESTRICTION_NONE);
             mPm.scheduleWritePackageRestrictions(userId);
         }
diff --git a/services/core/java/com/android/server/pm/InstallDependencyHelper.java b/services/core/java/com/android/server/pm/InstallDependencyHelper.java
index c0ddebe..837adf0 100644
--- a/services/core/java/com/android/server/pm/InstallDependencyHelper.java
+++ b/services/core/java/com/android/server/pm/InstallDependencyHelper.java
@@ -78,24 +78,22 @@
         mPackageInstallerService = packageInstallerService;
     }
 
-    void resolveLibraryDependenciesIfNeeded(PackageLite pkg, Computer snapshot, int userId,
-            Handler handler, OutcomeReceiver<Void, PackageManagerException> origCallback) {
+    void resolveLibraryDependenciesIfNeeded(List<SharedLibraryInfo> missingLibraries,
+            PackageLite pkg, Computer snapshot, int userId, Handler handler,
+            OutcomeReceiver<Void, PackageManagerException> origCallback) {
         CallOnceProxy callback = new CallOnceProxy(handler, origCallback);
         try {
-            resolveLibraryDependenciesIfNeededInternal(pkg, snapshot, userId, handler, callback);
-        } catch (PackageManagerException e) {
-            callback.onError(e);
+            resolveLibraryDependenciesIfNeededInternal(
+                    missingLibraries, pkg, snapshot, userId, handler, callback);
         } catch (Exception e) {
             onError(callback, e.getMessage());
         }
     }
 
 
-    private void resolveLibraryDependenciesIfNeededInternal(PackageLite pkg, Computer snapshot,
-            int userId, Handler handler, CallOnceProxy callback) throws PackageManagerException {
-        final List<SharedLibraryInfo> missing =
-                mSharedLibraries.collectMissingSharedLibraryInfos(pkg);
-
+    private void resolveLibraryDependenciesIfNeededInternal(List<SharedLibraryInfo> missing,
+            PackageLite pkg, Computer snapshot, int userId, Handler handler,
+            CallOnceProxy callback) {
         if (missing.isEmpty()) {
             if (DEBUG) {
                 Slog.d(TAG, "No missing dependency for " + pkg.getPackageName());
@@ -129,6 +127,11 @@
         }
     }
 
+    List<SharedLibraryInfo> getMissingSharedLibraries(PackageLite pkg)
+            throws PackageManagerException {
+        return mSharedLibraries.collectMissingSharedLibraryInfos(pkg);
+    }
+
     void notifySessionComplete(int sessionId) {
         if (DEBUG) {
             Slog.d(TAG, "Session complete for " + sessionId);
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 69c6ce8..b48b39c 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -2983,7 +2983,7 @@
         }
     }
 
-    public void sendPendingBroadcasts() {
+    public void sendPendingBroadcasts(String reasonForTrace) {
         String[] packages;
         ArrayList<String>[] components;
         int numBroadcasts = 0, numUsers;
@@ -3027,7 +3027,8 @@
         // Send broadcasts
         for (int i = 0; i < numBroadcasts; i++) {
             mBroadcastHelper.sendPackageChangedBroadcast(snapshot, packages[i],
-                    true /* dontKillApp */, components[i], uids[i], null /* reason */);
+                    true /* dontKillApp */, components[i], uids[i], null /* reason */,
+                    reasonForTrace);
         }
     }
 
@@ -3084,7 +3085,7 @@
                 mPm.mProcessLoggingHandler.invalidateBaseApkHash(request.getPkg().getBaseApkPath());
             }
 
-            mBroadcastHelper.sendPostInstallBroadcasts(mPm.snapshotComputer(), request, packageName,
+            mBroadcastHelper.sendPostInstallBroadcasts(mPm::snapshotComputer, request, packageName,
                     mPm.mRequiredPermissionControllerPackage, mPm.mRequiredVerifierPackages,
                     mPm.mRequiredInstallerPackage,
                     /* packageSender= */ mPm, launchedForRestore, killApp, update, archived);
diff --git a/services/core/java/com/android/server/pm/InstallRequest.java b/services/core/java/com/android/server/pm/InstallRequest.java
index b0fe3a9..c96c160 100644
--- a/services/core/java/com/android/server/pm/InstallRequest.java
+++ b/services/core/java/com/android/server/pm/InstallRequest.java
@@ -170,6 +170,8 @@
     private final boolean mHasAppMetadataFileFromInstaller;
 
     private boolean mKeepArtProfile = false;
+    private final boolean mDependencyInstallerEnabled;
+    private final int mMissingSharedLibraryCount;
 
     // New install
     InstallRequest(InstallingSession params) {
@@ -190,6 +192,8 @@
         mRequireUserAction = params.mRequireUserAction;
         mPreVerifiedDomains = params.mPreVerifiedDomains;
         mHasAppMetadataFileFromInstaller = params.mHasAppMetadataFile;
+        mDependencyInstallerEnabled = params.mDependencyInstallerEnabled;
+        mMissingSharedLibraryCount = params.mMissingSharedLibraryCount;
     }
 
     // Install existing package as user
@@ -209,6 +213,8 @@
         mInstallerUidForInstallExisting = installerUid;
         mSystem = isSystem;
         mHasAppMetadataFileFromInstaller = false;
+        mDependencyInstallerEnabled = false;
+        mMissingSharedLibraryCount = 0;
     }
 
     // addForInit
@@ -231,6 +237,8 @@
         mRequireUserAction = USER_ACTION_UNSPECIFIED;
         mDisabledPs = disabledPs;
         mHasAppMetadataFileFromInstaller = false;
+        mDependencyInstallerEnabled = false;
+        mMissingSharedLibraryCount = 0;
     }
 
     @Nullable
@@ -1069,4 +1077,12 @@
     boolean isKeepArtProfile() {
         return mKeepArtProfile;
     }
+
+    int getMissingSharedLibraryCount() {
+        return mMissingSharedLibraryCount;
+    }
+
+    boolean isDependencyInstallerEnabled() {
+        return mDependencyInstallerEnabled;
+    }
 }
diff --git a/services/core/java/com/android/server/pm/InstallingSession.java b/services/core/java/com/android/server/pm/InstallingSession.java
index ccc1175..6a2bf83 100644
--- a/services/core/java/com/android/server/pm/InstallingSession.java
+++ b/services/core/java/com/android/server/pm/InstallingSession.java
@@ -103,6 +103,8 @@
     final DomainSet mPreVerifiedDomains;
     final boolean mHasAppMetadataFile;
     @Nullable final String mDexoptCompilerFilter;
+    final boolean mDependencyInstallerEnabled;
+    final int mMissingSharedLibraryCount;
 
     // For move install
     InstallingSession(OriginInfo originInfo, MoveInfo moveInfo, IPackageInstallObserver2 observer,
@@ -138,13 +140,16 @@
         mPreVerifiedDomains = null;
         mHasAppMetadataFile = false;
         mDexoptCompilerFilter = null;
+        mDependencyInstallerEnabled = false;
+        mMissingSharedLibraryCount = 0;
     }
 
     InstallingSession(int sessionId, File stagedDir, IPackageInstallObserver2 observer,
             PackageInstaller.SessionParams sessionParams, InstallSource installSource,
             UserHandle user, SigningDetails signingDetails, int installerUid,
             PackageLite packageLite, DomainSet preVerifiedDomains, PackageManagerService pm,
-            boolean hasAppMetadatafile) {
+            boolean hasAppMetadatafile, boolean dependencyInstallerEnabled,
+            int missingSharedLibraryCount) {
         mPm = pm;
         mUser = user;
         mOriginInfo = OriginInfo.fromStagedFile(stagedDir);
@@ -175,6 +180,8 @@
         mPreVerifiedDomains = preVerifiedDomains;
         mHasAppMetadataFile = hasAppMetadatafile;
         mDexoptCompilerFilter = sessionParams.dexoptCompilerFilter;
+        mDependencyInstallerEnabled = dependencyInstallerEnabled;
+        mMissingSharedLibraryCount = missingSharedLibraryCount;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/PackageHandler.java b/services/core/java/com/android/server/pm/PackageHandler.java
index 4ea4054..0a06704 100644
--- a/services/core/java/com/android/server/pm/PackageHandler.java
+++ b/services/core/java/com/android/server/pm/PackageHandler.java
@@ -76,7 +76,7 @@
     void doHandleMessage(Message msg) {
         switch (msg.what) {
             case SEND_PENDING_BROADCAST: {
-                mPm.sendPendingBroadcasts();
+                mPm.sendPendingBroadcasts((String) msg.obj);
                 break;
             }
             case POST_INSTALL: {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 891d66a..c676043 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -31,6 +31,7 @@
 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
 import static android.content.pm.PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
+import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SPLIT;
 import static android.content.pm.PackageManager.INSTALL_FAILED_PRE_APPROVAL_NOT_AVAILABLE;
 import static android.content.pm.PackageManager.INSTALL_FAILED_SESSION_INVALID;
@@ -109,6 +110,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.PackageInfoFlags;
 import android.content.pm.PackageManagerInternal;
+import android.content.pm.SharedLibraryInfo;
 import android.content.pm.SigningDetails;
 import android.content.pm.dex.DexMetadataHelper;
 import android.content.pm.parsing.ApkLite;
@@ -540,6 +542,9 @@
     @GuardedBy("mLock")
     private DomainSet mPreVerifiedDomains;
 
+    private AtomicBoolean mDependencyInstallerEnabled = new AtomicBoolean();
+    private AtomicInteger mMissingSharedLibraryCount = new AtomicInteger();
+
     static class FileEntry {
         private final int mIndex;
         private final InstallationFile mFile;
@@ -3232,6 +3237,7 @@
         if (Flags.sdkDependencyInstaller()
                 && params.isAutoInstallDependenciesEnabled
                 && !isMultiPackage()) {
+            mDependencyInstallerEnabled.set(true);
             resolveLibraryDependenciesIfNeeded();
         } else {
             install();
@@ -3241,8 +3247,20 @@
 
     private void resolveLibraryDependenciesIfNeeded() {
         synchronized (mLock) {
-            mInstallDependencyHelper.resolveLibraryDependenciesIfNeeded(mPackageLite,
-                    mPm.snapshotComputer(), userId, mHandler,
+            List<SharedLibraryInfo> missingLibraries = new ArrayList<>();
+            try {
+                missingLibraries = mInstallDependencyHelper.getMissingSharedLibraries(mPackageLite);
+            } catch (PackageManagerException e) {
+                handleDependencyResolutionFailure(e);
+            } catch (Exception e) {
+                handleDependencyResolutionFailure(
+                        new PackageManagerException(
+                                INSTALL_FAILED_MISSING_SHARED_LIBRARY, e.getMessage()));
+            }
+
+            mMissingSharedLibraryCount.set(missingLibraries.size());
+            mInstallDependencyHelper.resolveLibraryDependenciesIfNeeded(missingLibraries,
+                    mPackageLite, mPm.snapshotComputer(), userId, mHandler,
                     new OutcomeReceiver<>() {
 
                         @Override
@@ -3252,14 +3270,21 @@
 
                         @Override
                         public void onError(@NonNull PackageManagerException e) {
-                            final String completeMsg = ExceptionUtils.getCompleteMessage(e);
-                            setSessionFailed(e.error, completeMsg);
-                            onSessionDependencyResolveFailure(e.error, completeMsg);
+                            handleDependencyResolutionFailure(e);
                         }
                     });
         }
     }
 
+    private void handleDependencyResolutionFailure(@NonNull PackageManagerException e) {
+        final String completeMsg = ExceptionUtils.getCompleteMessage(e);
+        setSessionFailed(e.error, completeMsg);
+        onSessionDependencyResolveFailure(e.error, completeMsg);
+        PackageMetrics.onDependencyInstallationFailure(
+                sessionId, getPackageName(), e.error, mInstallerUid, params,
+                mMissingSharedLibraryCount.get());
+    }
+
     /**
      * Stages this session for install and returns a
      * {@link InstallingSession} representing this new staged state.
@@ -3327,7 +3352,8 @@
         synchronized (mLock) {
             return new InstallingSession(sessionId, stageDir, localObserver, params, mInstallSource,
                     user, mSigningDetails, mInstallerUid, mPackageLite, mPreVerifiedDomains, mPm,
-                    mHasAppMetadataFile);
+                    mHasAppMetadataFile, mDependencyInstallerEnabled.get(),
+                    mMissingSharedLibraryCount.get());
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 65bb701..a0bbc45 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3020,6 +3020,16 @@
         mDexOptHelper.performPackageDexOptUpgradeIfNeeded();
     }
 
+    public void updateMetricsIfNeeded() {
+        final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
+        if (displayManager != null) {
+            final Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
+            if (display != null) {
+                display.getMetrics(mMetrics);
+            }
+        }
+    }
+
     private void notifyPackageUseInternal(String packageName, int reason) {
         long time = System.currentTimeMillis();
         synchronized (mLock) {
@@ -3531,7 +3541,10 @@
 
         mPendingBroadcasts.addComponents(userId, packageName, updatedComponents);
         if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
-            mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
+            mHandler.sendMessageDelayed(
+                    mHandler.obtainMessage(SEND_PENDING_BROADCAST,
+                            "reset_component_state_changed" /* obj */),
+                    BROADCAST_DELAY);
         }
     }
 
@@ -3828,7 +3841,8 @@
         mPendingBroadcasts.addComponent(userId, componentPkgName, componentName.getClassName());
 
         if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
-            mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
+            mHandler.sendMessageDelayed(mHandler.obtainMessage(SEND_PENDING_BROADCAST,
+                    "component_label_icon_changed" /* obj */), BROADCAST_DELAY);
         }
     }
 
@@ -4063,6 +4077,8 @@
                     mPendingBroadcasts.remove(userId, packageName);
                 } else {
                     mPendingBroadcasts.addComponent(userId, packageName, componentName);
+                    Trace.instant(Trace.TRACE_TAG_PACKAGE_MANAGER, "setEnabledSetting broadcast: "
+                                   + componentName + ": " + setting.getEnabledState());
                     scheduleBroadcastMessage = true;
                 }
             }
@@ -4085,7 +4101,8 @@
                     final long broadcastDelay = SystemClock.uptimeMillis() > mServiceStartWithDelay
                             ? BROADCAST_DELAY
                             : BROADCAST_DELAY_DURING_STARTUP;
-                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, broadcastDelay);
+                    mHandler.sendMessageDelayed(mHandler.obtainMessage(SEND_PENDING_BROADCAST,
+                            "component_state_changed" /* obj */), broadcastDelay);
                 }
             }
         }
@@ -4103,7 +4120,8 @@
                 final int packageUid = UserHandle.getUid(
                         userId, pkgSettings.get(packageName).getAppId());
                 mBroadcastHelper.sendPackageChangedBroadcast(newSnapshot, packageName,
-                        false /* dontKillApp */, components, packageUid, null /* reason */);
+                        false /* dontKillApp */, components, packageUid, null /* reason */,
+                        "component_state_changed" /* reasonForTrace */);
             }
         } finally {
             Binder.restoreCallingIdentity(callingId);
@@ -4331,7 +4349,7 @@
                         true /* dontKillApp */,
                         new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
                         pkg.getUid(),
-                        Intent.ACTION_OVERLAY_CHANGED);
+                        Intent.ACTION_OVERLAY_CHANGED, "overlay_changed" /* reasonForTrace */);
             }
         }, overlayFilter);
 
@@ -6382,7 +6400,8 @@
                         if (pkgUserState != null && pkgUserState.isInstalled()) {
                             final int packageUid = UserHandle.getUid(userIds[i], appId);
                             mBroadcastHelper.sendPackageChangedBroadcast(snapShot, packageName,
-                                    true /* dontKillApp */, components, packageUid, reason);
+                                    true /* dontKillApp */, components, packageUid, reason,
+                                    "mime_group_changed" /* reasonForTrace */);
                         }
                     }
                 });
@@ -8177,8 +8196,8 @@
         mRemovePackageHelper.cleanUpForMoveInstall(volumeUuid, packageName, fromCodePath);
     }
 
-    void sendPendingBroadcasts() {
-        mInstallPackageHelper.sendPendingBroadcasts();
+    void sendPendingBroadcasts(String reasonForTrace) {
+        mInstallPackageHelper.sendPendingBroadcasts(reasonForTrace);
     }
 
     void handlePackagePostInstall(@NonNull InstallRequest request, boolean launchedForRestore) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 9757582..7af39f7 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -749,7 +749,7 @@
                     null /*abiOverride*/, false /*isIncremental*/);
         } catch (IOException e) {
             logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
-                    + "; pkg: " + packageName);
+                    + "; pkg: " + packageName + "; err: " + e.getMessage());
             return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
         } finally {
             IoUtils.closeQuietly(handle);
diff --git a/services/core/java/com/android/server/pm/PackageMetrics.java b/services/core/java/com/android/server/pm/PackageMetrics.java
index 0acadb1..856d6a7 100644
--- a/services/core/java/com/android/server/pm/PackageMetrics.java
+++ b/services/core/java/com/android/server/pm/PackageMetrics.java
@@ -32,7 +32,9 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.content.pm.DataLoaderType;
 import android.content.pm.Flags;
+import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.parsing.ApkLiteParseUtils;
@@ -173,7 +175,10 @@
                 mInstallRequest.isInstallInherit() /* is_inherit */,
                 mInstallRequest.isInstallForUsers() /* is_installing_existing_as_user */,
                 mInstallRequest.isInstallMove() /* is_move_install */,
-                false /* is_staged */
+                false /* is_staged */,
+                mInstallRequest
+                        .isDependencyInstallerEnabled() /* is_install_dependencies_enabled */,
+                mInstallRequest.getMissingSharedLibraryCount() /* missing_dependencies_count */
         );
     }
 
@@ -323,7 +328,53 @@
                 verifyingSession.isInherit() /* is_inherit */,
                 false /* is_installing_existing_as_user */,
                 false /* is_move_install */,
-                verifyingSession.isStaged() /* is_staged */
+                verifyingSession.isStaged() /* is_staged */,
+                false /* is_install_dependencies_enabled */,
+                0 /* missing_dependencies_count */
+        );
+    }
+
+    static void onDependencyInstallationFailure(
+            int sessionId, String packageName, int errorCode, int installerPackageUid,
+            PackageInstaller.SessionParams params, int missingDependenciesCount) {
+        if (params == null) {
+            return;
+        }
+        int dataLoaderType = DataLoaderType.NONE;
+        if (params.dataLoaderParams != null) {
+            dataLoaderType = params.dataLoaderParams.getType();
+        }
+
+        FrameworkStatsLog.write(FrameworkStatsLog.PACKAGE_INSTALLATION_SESSION_REPORTED,
+                sessionId /* session_id */,
+                packageName /* package_name */,
+                INVALID_UID /* uid */,
+                null /* user_ids */,
+                null /* user_types */,
+                null /* original_user_ids */,
+                null /* original_user_types */,
+                errorCode /* public_return_code */,
+                0 /* internal_error_code */,
+                0 /* apks_size_bytes */,
+                0 /* version_code */,
+                null /* install_steps */,
+                null /* step_duration_millis */,
+                0 /* total_duration_millis */,
+                0 /* install_flags */,
+                installerPackageUid /* installer_package_uid */,
+                INVALID_UID /* original_installer_package_uid */,
+                dataLoaderType /* data_loader_type */,
+                params.requireUserAction /* user_action_required_type */,
+                (params.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0 /* is_instant */,
+                false /* is_replace */,
+                false /* is_system */,
+                params.mode
+                        == PackageInstaller.SessionParams.MODE_INHERIT_EXISTING /* is_inherit */,
+                false /* is_installing_existing_as_user */,
+                false /* is_move_install */,
+                params.isStaged /* is_staged */,
+                true /* is_install_dependencies_enabled */,
+                missingDependenciesCount /* missing_dependencies_count */
         );
     }
 
diff --git a/services/core/java/com/android/server/pm/StorageEventHelper.java b/services/core/java/com/android/server/pm/StorageEventHelper.java
index 951986f..a09d477 100644
--- a/services/core/java/com/android/server/pm/StorageEventHelper.java
+++ b/services/core/java/com/android/server/pm/StorageEventHelper.java
@@ -227,7 +227,7 @@
         }
 
         if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
-        mBroadcastHelper.sendResourcesChangedBroadcastAndNotify(mPm.snapshotComputer(),
+        mBroadcastHelper.sendResourcesChangedBroadcastAndNotify(mPm::snapshotComputer,
                 true /* mediaStatus */, false /* replacing */, loaded);
         synchronized (mLoadedVolumes) {
             mLoadedVolumes.add(vol.getId());
@@ -279,7 +279,7 @@
         }
 
         if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
-        mBroadcastHelper.sendResourcesChangedBroadcastAndNotify(mPm.snapshotComputer(),
+        mBroadcastHelper.sendResourcesChangedBroadcastAndNotify(mPm::snapshotComputer,
                 false /* mediaStatus */, false /* replacing */, unloaded);
         synchronized (mLoadedVolumes) {
             mLoadedVolumes.remove(vol.getId());
diff --git a/services/core/java/com/android/server/pm/SuspendPackageHelper.java b/services/core/java/com/android/server/pm/SuspendPackageHelper.java
index 4e70cc5..88fd1aa 100644
--- a/services/core/java/com/android/server/pm/SuspendPackageHelper.java
+++ b/services/core/java/com/android/server/pm/SuspendPackageHelper.java
@@ -192,21 +192,20 @@
             }
         });
 
-        final Computer newSnapshot = mPm.snapshotComputer();
         if (!notifyPackagesList.isEmpty()) {
             final String[] changedPackages =
                     notifyPackagesList.toArray(new String[0]);
-            mBroadcastHelper.sendPackagesSuspendedOrUnsuspendedForUser(newSnapshot,
+            mBroadcastHelper.sendPackagesSuspendedOrUnsuspendedForUser(mPm::snapshotComputer,
                     suspended ? Intent.ACTION_PACKAGES_SUSPENDED
                             : Intent.ACTION_PACKAGES_UNSUSPENDED,
                     changedPackages, notifyUids.toArray(), quarantined, targetUserId);
-            mBroadcastHelper.sendMyPackageSuspendedOrUnsuspended(newSnapshot, changedPackages,
-                    suspended, targetUserId);
+            mBroadcastHelper.sendMyPackageSuspendedOrUnsuspended(mPm::snapshotComputer,
+                    changedPackages, suspended, targetUserId);
             mPm.scheduleWritePackageRestrictions(targetUserId);
         }
         // Send the suspension changed broadcast to ensure suspension state is not stale.
         if (!changedPackagesList.isEmpty()) {
-            mBroadcastHelper.sendPackagesSuspendedOrUnsuspendedForUser(newSnapshot,
+            mBroadcastHelper.sendPackagesSuspendedOrUnsuspendedForUser(mPm::snapshotComputer,
                     Intent.ACTION_PACKAGES_SUSPENSION_CHANGED,
                     changedPackagesList.toArray(new String[0]), changedUids.toArray(), quarantined,
                     targetUserId);
@@ -343,13 +342,12 @@
         });
 
         mPm.scheduleWritePackageRestrictions(targetUserId);
-        final Computer newSnapshot = mPm.snapshotComputer();
         if (!unsuspendedPackages.isEmpty()) {
             final String[] packageArray = unsuspendedPackages.toArray(
                     new String[unsuspendedPackages.size()]);
-            mBroadcastHelper.sendMyPackageSuspendedOrUnsuspended(newSnapshot, packageArray,
-                    false, targetUserId);
-            mBroadcastHelper.sendPackagesSuspendedOrUnsuspendedForUser(newSnapshot,
+            mBroadcastHelper.sendMyPackageSuspendedOrUnsuspended(mPm::snapshotComputer,
+                    packageArray, false, targetUserId);
+            mBroadcastHelper.sendPackagesSuspendedOrUnsuspendedForUser(mPm::snapshotComputer,
                     Intent.ACTION_PACKAGES_UNSUSPENDED,
                     packageArray, unsuspendedUids.toArray(), false, targetUserId);
         }
diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java
index 041f2d3..04ce4e6 100644
--- a/services/core/java/com/android/server/pm/UserDataPreparer.java
+++ b/services/core/java/com/android/server/pm/UserDataPreparer.java
@@ -68,6 +68,10 @@
     void prepareUserData(UserInfo userInfo, int flags) {
         try (PackageManagerTracedLock installLock = mInstallLock.acquireLock()) {
             final StorageManager storage = mContext.getSystemService(StorageManager.class);
+            if (storage == null) {
+                Log.e(TAG, "prepareUserData failed due to unable get StorageManager");
+                return;
+            }
             /*
              * Internal storage must be prepared before adoptable storage, since the user's volume
              * keys are stored in their internal storage.
@@ -159,14 +163,16 @@
     void destroyUserData(int userId, int flags) {
         try (PackageManagerTracedLock installLock = mInstallLock.acquireLock()) {
             final StorageManager storage = mContext.getSystemService(StorageManager.class);
-            /*
-             * Volume destruction order isn't really important, but to avoid any weird issues we
-             * process internal storage last, the opposite of prepareUserData.
-             */
-            for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
-                final String volumeUuid = vol.getFsUuid();
-                if (volumeUuid != null) {
-                    destroyUserDataLI(volumeUuid, userId, flags);
+            if (storage != null) {
+                /*
+                 * Volume destruction order isn't really important, but to avoid any weird issues we
+                 * process internal storage last, the opposite of prepareUserData.
+                 */
+                for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
+                    final String volumeUuid = vol.getFsUuid();
+                    if (volumeUuid != null) {
+                        destroyUserDataLI(volumeUuid, userId, flags);
+                    }
                 }
             }
             destroyUserDataLI(null /* internal storage */, userId, flags);
@@ -194,9 +200,10 @@
                 }
             }
 
-            // All the user's data directories should be empty now, so finish the job.
-            storage.destroyUserStorage(volumeUuid, userId, flags);
-
+            if (storage != null) {
+                // All the user's data directories should be empty now, so finish the job.
+                storage.destroyUserStorage(volumeUuid, userId, flags);
+            }
         } catch (Exception e) {
             logCriticalInfo(Log.WARN,
                     "Failed to destroy user " + userId + " on volume " + volumeUuid + ": " + e);
diff --git a/services/core/java/com/android/server/pm/VerifyingSession.java b/services/core/java/com/android/server/pm/VerifyingSession.java
index 542ae8e..dd60a15 100644
--- a/services/core/java/com/android/server/pm/VerifyingSession.java
+++ b/services/core/java/com/android/server/pm/VerifyingSession.java
@@ -16,11 +16,7 @@
 
 package com.android.server.pm;
 
-import static android.content.Intent.EXTRA_LONG_VERSION_CODE;
-import static android.content.Intent.EXTRA_PACKAGE_NAME;
-import static android.content.Intent.EXTRA_VERSION_CODE;
 import static android.content.pm.PackageInstaller.SessionParams.MODE_INHERIT_EXISTING;
-import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ID;
 import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
 import static android.content.pm.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4;
@@ -40,9 +36,7 @@
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
 import android.app.BroadcastOptions;
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
-import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.DataLoaderType;
@@ -68,7 +62,6 @@
 import android.os.UserManager;
 import android.os.incremental.IncrementalManager;
 import android.provider.DeviceConfig;
-import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Pair;
 import android.util.Slog;
diff --git a/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java b/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java
index e989d68..e9cb279 100644
--- a/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java
+++ b/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java
@@ -40,7 +40,7 @@
 import com.android.internal.util.function.DodecFunction;
 import com.android.internal.util.function.HexConsumer;
 import com.android.internal.util.function.HexFunction;
-import com.android.internal.util.function.NonaFunction;
+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;
@@ -351,22 +351,22 @@
         @Override
         public SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName,
                 @Nullable String featureId, int virtualDeviceId, boolean shouldCollectAsyncNotedOp,
-                @Nullable String message, boolean shouldCollectMessage, int notedCount,
-                @NonNull NonaFunction<Integer, Integer, String, String, Integer, Boolean, String,
-                                        Boolean, Integer, SyncNotedAppOp> superImpl) {
+                @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, SHELL_PKG, featureId, virtualDeviceId,
-                            shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount);
+                            shouldCollectAsyncNotedOp, message, shouldCollectMessage);
                 } finally {
                     Binder.restoreCallingIdentity(identity);
                 }
             }
             return superImpl.apply(code, uid, packageName, featureId, virtualDeviceId,
-                    shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount);
+                    shouldCollectAsyncNotedOp, message, shouldCollectMessage);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index 33210e2..ecffd38 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -53,7 +53,7 @@
 import com.android.internal.util.function.DodecFunction;
 import com.android.internal.util.function.HexConsumer;
 import com.android.internal.util.function.HexFunction;
-import com.android.internal.util.function.NonaFunction;
+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.LocalServices;
@@ -246,12 +246,11 @@
     public SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName,
             @Nullable String attributionTag, int virtualDeviceId,
             boolean shouldCollectAsyncNotedOp, @Nullable String message,
-            boolean shouldCollectMessage, int notedCount,
-            @NonNull NonaFunction<Integer, Integer, String, String,
-                    Integer, Boolean, String, Boolean, Integer, SyncNotedAppOp> superImpl) {
+            boolean shouldCollectMessage, @NonNull OctFunction<Integer, Integer, String, String,
+                    Integer, Boolean, String, Boolean, SyncNotedAppOp> superImpl) {
         return superImpl.apply(resolveDatasourceOp(code, uid, packageName, attributionTag),
                 resolveUid(code, uid), packageName, attributionTag, virtualDeviceId,
-                shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount);
+                shouldCollectAsyncNotedOp, message, shouldCollectMessage);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index f1a4811..c4d1cc7 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3576,7 +3576,7 @@
                 }
                 break;
             case KeyEvent.KEYCODE_I:
-                if (firstDown && event.isMetaPressed()) {
+                if (firstDown && event.isMetaPressed() && isUserSetupComplete() && !keyguardOn) {
                     showSystemSettings();
                     notifyKeyGestureCompleted(event,
                             KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS);
@@ -4106,6 +4106,7 @@
                     case KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_SHORTCUT:
                     case KeyGestureEvent.KEY_GESTURE_TYPE_CLOSE_ALL_DIALOGS:
                     case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION:
+                    case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB:
                         return true;
                     case KeyGestureEvent.KEY_GESTURE_TYPE_SCREENSHOT_CHORD:
                     case KeyGestureEvent.KEY_GESTURE_TYPE_RINGER_TOGGLE_CHORD:
@@ -4120,18 +4121,6 @@
                                 .isAccessibilityShortcutAvailable(false);
                     case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK:
                         return enableTalkbackAndMagnifierKeyGestures();
-                    case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS:
-                        return InputSettings.isAccessibilitySlowKeysFeatureFlagEnabled()
-                                && keyboardA11yShortcutControl();
-                    case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_BOUNCE_KEYS:
-                        return InputSettings.isAccessibilityBounceKeysFeatureEnabled()
-                                && keyboardA11yShortcutControl();
-                    case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS:
-                        return InputSettings.isAccessibilityMouseKeysFeatureFlagEnabled()
-                                && keyboardA11yShortcutControl();
-                    case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_STICKY_KEYS:
-                        return InputSettings.isAccessibilityStickyKeysFeatureEnabled()
-                                && keyboardA11yShortcutControl();
                     default:
                         return false;
                 }
@@ -4149,6 +4138,7 @@
         int displayId = event.getDisplayId();
         int modifierState = event.getModifierState();
         boolean keyguardOn = keyguardOn();
+        boolean canLaunchApp = isUserSetupComplete() && !keyguardOn;
         switch (gestureType) {
             case KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS:
                 if (complete) {
@@ -4166,7 +4156,7 @@
                 return true;
             case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT:
             case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT:
-                if (complete) {
+                if (complete && canLaunchApp) {
                     launchAssistAction(Intent.EXTRA_ASSIST_INPUT_HINT_KEYBOARD,
                             deviceId, SystemClock.uptimeMillis(),
                             AssistUtils.INVOCATION_TYPE_UNKNOWN);
@@ -4179,7 +4169,7 @@
                 }
                 return true;
             case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS:
-                if (complete) {
+                if (complete && canLaunchApp) {
                     showSystemSettings();
                 }
                 return true;
@@ -4282,7 +4272,7 @@
                 }
                 return true;
             case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SEARCH:
-                if (complete) {
+                if (complete && canLaunchApp) {
                     launchTargetSearchActivity();
                 }
                 return true;
@@ -4363,63 +4353,20 @@
                 break;
             case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION:
                 AppLaunchData data = event.getAppLaunchData();
-                if (complete && isUserSetupComplete() && !keyguardOn
-                        && data != null && mModifierShortcutManager.launchApplication(data)) {
+                if (complete && canLaunchApp && data != null
+                        && mModifierShortcutManager.launchApplication(data)) {
                     dismissKeyboardShortcutsMenu();
                 }
                 return true;
-            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_BOUNCE_KEYS:
-                if (InputSettings.isAccessibilityBounceKeysFeatureEnabled()
-                        && keyboardA11yShortcutControl()) {
-                    if (complete) {
-                        final boolean bounceKeysEnabled =
-                                InputSettings.isAccessibilityBounceKeysEnabled(
-                                        mContext);
-                        InputSettings.setAccessibilityBounceKeysThreshold(mContext,
-                                bounceKeysEnabled ? 0
-                                        : InputSettings.DEFAULT_BOUNCE_KEYS_THRESHOLD_MILLIS);
-                    }
-                    return true;
+            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB:
+                NotificationManager nm = getNotificationService();
+                if (nm != null) {
+                    boolean isEnabled = nm.getZenMode() != Settings.Global.ZEN_MODE_OFF;
+                    nm.setZenMode(isEnabled ? Settings.Global.ZEN_MODE_OFF
+                                    : Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
+                            "Key gesture DND", true);
                 }
-                break;
-            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS:
-                if (InputSettings.isAccessibilityMouseKeysFeatureFlagEnabled()
-                        && keyboardA11yShortcutControl()) {
-                    if (complete) {
-                        final boolean mouseKeysEnabled =
-                                InputSettings.isAccessibilityMouseKeysEnabled(
-                                        mContext);
-                        InputSettings.setAccessibilityMouseKeysEnabled(mContext,
-                                !mouseKeysEnabled);
-                    }
-                    return true;
-                }
-                break;
-            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_STICKY_KEYS:
-                if (InputSettings.isAccessibilityStickyKeysFeatureEnabled()
-                        && keyboardA11yShortcutControl()) {
-                    if (complete) {
-                        final boolean stickyKeysEnabled =
-                                InputSettings.isAccessibilityStickyKeysEnabled(mContext);
-                        InputSettings.setAccessibilityStickyKeysEnabled(mContext,
-                                !stickyKeysEnabled);
-                    }
-                    return true;
-                }
-                break;
-            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS:
-                if (InputSettings.isAccessibilitySlowKeysFeatureFlagEnabled()
-                        && keyboardA11yShortcutControl()) {
-                    if (complete) {
-                        final boolean slowKeysEnabled =
-                                InputSettings.isAccessibilitySlowKeysEnabled(mContext);
-                        InputSettings.setAccessibilitySlowKeysThreshold(mContext,
-                                slowKeysEnabled ? 0
-                                        : InputSettings.DEFAULT_SLOW_KEYS_THRESHOLD_MILLIS);
-                    }
-                    return true;
-                }
-                break;
+                return true;
         }
         return false;
     }
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 36bc0b9..ce8dc69 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -7093,7 +7093,11 @@
                     if ((flags & PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP) != 0) {
                         if (mFoldGracePeriodProvider.isEnabled()) {
                             if (!powerGroup.hasWakeLockKeepingScreenOnLocked()) {
+                                Slog.d(TAG, "Showing dismissible keyguard");
                                 mNotifier.showDismissibleKeyguard();
+                            } else {
+                                Slog.i(TAG, "There is a screen wake lock present: "
+                                        + "sleep request will be ignored");
                             }
                             continue; // never actually goes to sleep for SOFT_SLEEP
                         } else {
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 987a849..137ea06 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -296,7 +296,11 @@
         mPowerHalVersion = 0;
         mUsesFmq = false;
         if (mPowerHal != null) {
-            mSupportInfo = getSupportInfo();
+            try {
+                mSupportInfo = getSupportInfo();
+            } catch (RemoteException e) {
+                throw new IllegalStateException("Could not contact PowerHAL!", e);
+            }
         }
         mDefaultCpuHeadroomCalculationWindowMillis =
                 new CpuHeadroomParamsInternal().calculationWindowMillis;
@@ -314,7 +318,7 @@
         }
     }
 
-    SupportInfo getSupportInfo() {
+    SupportInfo getSupportInfo() throws RemoteException {
         try {
             mPowerHalVersion = mPowerHal.getInterfaceVersion();
             if (mPowerHalVersion >= 6) {
@@ -325,9 +329,40 @@
         }
 
         SupportInfo supportInfo = new SupportInfo();
+        supportInfo.usesSessions = isHintSessionSupported();
+        // Global boosts & modes aren't currently relevant for HMS clients
+        supportInfo.boosts = 0;
+        supportInfo.modes = 0;
+        supportInfo.sessionHints = 0;
+        supportInfo.sessionModes = 0;
+        supportInfo.sessionTags = 0;
+
         supportInfo.headroom = new SupportInfo.HeadroomSupportInfo();
         supportInfo.headroom.isCpuSupported = false;
         supportInfo.headroom.isGpuSupported = false;
+        if (isHintSessionSupported()) {
+            if (mPowerHalVersion == 4) {
+                // Assume we support the V4 hints & modes unless specified
+                // otherwise; this is to avoid breaking backwards compat
+                // since we historically just assumed they were.
+                supportInfo.sessionHints = 31; // first 5 bits are ones
+            }
+            if (mPowerHalVersion == 5) {
+                // Assume we support the V5 hints & modes unless specified
+                // otherwise; this is to avoid breaking backwards compat
+                // since we historically just assumed they were.
+
+                // Hal V5 has 8 modes, all of which it assumes are supported,
+                // so we represent that by having the first 8 bits set
+                supportInfo.sessionHints = 255; // first 8 bits are ones
+                // Hal V5 has 1 mode which it assumes is supported, so we
+                // represent that by having the first bit set
+                supportInfo.sessionModes = 1;
+                // Hal V5 has 5 tags, all of which it assumes are supported,
+                // so we represent that by having the first 5 bits set
+                supportInfo.sessionTags = 31;
+            }
+        }
         return supportInfo;
     }
 
@@ -1228,7 +1263,7 @@
                     @SessionTag int tag, SessionCreationConfig creationConfig,
                     SessionConfig config) {
             if (!isHintSessionSupported()) {
-                throw new UnsupportedOperationException("PowerHAL is not supported!");
+                throw new UnsupportedOperationException("PowerHintSessions are not supported!");
             }
 
             java.util.Objects.requireNonNull(token);
@@ -1424,12 +1459,6 @@
             removeChannelItem(callingTgid, callingUid);
         };
 
-        @Override
-        public long getHintSessionPreferredRate() {
-            return mHintSessionPreferredRate;
-        }
-
-        @Override
         public int getMaxGraphicsPipelineThreadsCount() {
             return MAX_GRAPHICS_PIPELINE_THREADS_COUNT;
         }
@@ -1561,6 +1590,16 @@
             mSessionManager = ISessionManager.Stub.asInterface(sessionManager);
         }
 
+        public IHintManager.HintManagerClientData
+                registerClient(@NonNull IHintManager.IHintManagerClient clientBinder) {
+            IHintManager.HintManagerClientData out = new IHintManager.HintManagerClientData();
+            out.preferredRateNanos = mHintSessionPreferredRate;
+            out.maxGraphicsPipelineThreads = getMaxGraphicsPipelineThreadsCount();
+            out.powerHalVersion = mPowerHalVersion;
+            out.supportInfo = mSupportInfo;
+            return out;
+        }
+
         @Override
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) {
@@ -1568,7 +1607,7 @@
             }
             pw.println("HintSessionPreferredRate: " + mHintSessionPreferredRate);
             pw.println("MaxGraphicsPipelineThreadsCount: " + MAX_GRAPHICS_PIPELINE_THREADS_COUNT);
-            pw.println("HAL Support: " + isHintSessionSupported());
+            pw.println("Hint Session Support: " + isHintSessionSupported());
             pw.println("Active Sessions:");
             synchronized (mLock) {
                 for (int i = 0; i < mActiveSessions.size(); i++) {
diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
index 6f18107..c26eeed 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -5723,7 +5723,9 @@
                     displayStats.screenDozeTimer.stopRunningLocked(elapsedRealtimeMs);
                     shouldScheduleSync = true;
                     break;
-                case Display.STATE_OFF: // fallthrough
+                case Display.STATE_OFF:
+                    shouldScheduleSync = true;
+                    break;
                 case Display.STATE_UNKNOWN:
                     // Not tracked by timers.
                     break;
@@ -5756,7 +5758,9 @@
                     displayStats.screenDozeTimer.startRunningLocked(elapsedRealtimeMs);
                     shouldScheduleSync = true;
                     break;
-                case Display.STATE_OFF: // fallthrough
+                case Display.STATE_OFF:
+                    shouldScheduleSync = true;
+                    break;
                 case Display.STATE_UNKNOWN:
                     // Not tracked by timers.
                     break;
@@ -5873,7 +5877,7 @@
 
         if (shouldScheduleSync) {
             if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_SCREEN)) {
-                mScreenPowerStatsCollector.schedule();
+                mScreenPowerStatsCollector.onScreenStateChange();
             } else {
                 final int numDisplays = mPerDisplayBatteryStats.length;
                 final int[] displayStates = new int[numDisplays];
diff --git a/services/core/java/com/android/server/power/stats/ScreenPowerStatsCollector.java b/services/core/java/com/android/server/power/stats/ScreenPowerStatsCollector.java
index c38904f..90039e8 100644
--- a/services/core/java/com/android/server/power/stats/ScreenPowerStatsCollector.java
+++ b/services/core/java/com/android/server/power/stats/ScreenPowerStatsCollector.java
@@ -111,6 +111,22 @@
         return true;
     }
 
+    /**
+     * Must be called whenever the screen state (on/off/doze) changes.
+     */
+    public void onScreenStateChange() {
+        if (ensureInitialized() && mConsumedEnergyHelper.getEnergyConsumerCount() != 0) {
+            // Sync power monitor reading immediately, because the estimation algorithm
+            // distributes consumed power proportionally between screen states.
+            // Since screen power consumption differs dramatically between different states,
+            // this would lead an overestimation in the screen-off state.
+            forceSchedule();
+            return;
+        }
+        // Perhaps schedule a sync, allowing throttling
+        schedule();
+    }
+
     @Override
     public PowerStats collectStats() {
         if (!ensureInitialized()) {
@@ -126,7 +142,7 @@
             long screenOnTimeMs = mScreenUsageTimeRetriever.getScreenOnTimeMs(display);
             if (!mFirstSample) {
                 mLayout.setScreenOnDuration(mPowerStats.stats, display,
-                        screenOnTimeMs - mLastScreenOnTime[display]);
+                        Math.max(0, screenOnTimeMs - mLastScreenOnTime[display]));
             }
             mLastScreenOnTime[display] = screenOnTimeMs;
 
@@ -135,14 +151,15 @@
                         mScreenUsageTimeRetriever.getBrightnessLevelTimeMs(display, level);
                 if (!mFirstSample) {
                     mLayout.setBrightnessLevelDuration(mPowerStats.stats, display, level,
-                            brightnessLevelTimeMs - mLastBrightnessLevelTime[display][level]);
+                            Math.max(0, brightnessLevelTimeMs
+                                    - mLastBrightnessLevelTime[display][level]));
                 }
                 mLastBrightnessLevelTime[display][level] = brightnessLevelTimeMs;
             }
             long screenDozeTimeMs = mScreenUsageTimeRetriever.getScreenDozeTimeMs(display);
             if (!mFirstSample) {
                 mLayout.setScreenDozeDuration(mPowerStats.stats, display,
-                        screenDozeTimeMs - mLastDozeTime[display]);
+                        Math.max(0, screenDozeTimeMs - mLastDozeTime[display]));
             }
             mLastDozeTime[display] = screenDozeTimeMs;
         }
@@ -162,7 +179,7 @@
             }
 
             mLayout.setUidTopActivityDuration(uidStats,
-                    mLayout.getUidTopActivityDuration(uidStats) + topActivityDuration);
+                    Math.max(0, mLayout.getUidTopActivityDuration(uidStats) + topActivityDuration));
         });
 
         long elapsedRealtime = mClock.elapsedRealtime();
diff --git a/services/core/java/com/android/server/power/stats/processor/PowerStatsAggregator.java b/services/core/java/com/android/server/power/stats/processor/PowerStatsAggregator.java
index 2609cf7..1b864bb 100644
--- a/services/core/java/com/android/server/power/stats/processor/PowerStatsAggregator.java
+++ b/services/core/java/com/android/server/power/stats/processor/PowerStatsAggregator.java
@@ -170,13 +170,15 @@
                     }
                 }
             }
-            if (endTimeMs != MonotonicClock.UNDEFINED) {
-                lastTime = endTimeMs;
-            }
-            if (lastTime > baseTime) {
-                mStats.setDuration(lastTime - baseTime);
-                mStats.finish(lastTime);
-                consumer.accept(mStats);
+            if (startedSession) {
+                if (endTimeMs != MonotonicClock.UNDEFINED) {
+                    lastTime = endTimeMs;
+                }
+                if (lastTime > baseTime) {
+                    mStats.setDuration(lastTime - baseTime);
+                    mStats.finish(lastTime);
+                    consumer.accept(mStats);
+                }
             }
 
             mStats.reset();     // to free up memory
diff --git a/services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java b/services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java
index bb523d6..59bb34d 100644
--- a/services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java
+++ b/services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java
@@ -19,24 +19,13 @@
 import static android.security.advancedprotection.AdvancedProtectionManager.ADVANCED_PROTECTION_SYSTEM_ENTITY;
 import static android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES;
 
-import android.Manifest;
 import android.annotation.NonNull;
-import android.app.ActivityManagerInternal;
-import android.app.AppGlobals;
-import android.app.AppOpsManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
-import android.os.Process;
-import android.os.RemoteException;
 import android.os.UserManager;
 import android.security.advancedprotection.AdvancedProtectionFeature;
 import android.util.Slog;
 
-import com.android.server.LocalServices;
-
 /** @hide */
 public final class DisallowInstallUnknownSourcesAdvancedProtectionHook
         extends AdvancedProtectionHook {
@@ -45,24 +34,14 @@
     private final AdvancedProtectionFeature mFeature = new AdvancedProtectionFeature(
             FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES);
 
-    private final ActivityManagerInternal mActivityManagerInternal;
-    private final AppOpsManager mAppOpsManager;
     private final DevicePolicyManager mDevicePolicyManager;
-    private final IPackageManager mIPackageManager;
-    private final PackageManager mPackageManager;
-    private final UserManager mUserManager;
 
     public DisallowInstallUnknownSourcesAdvancedProtectionHook(@NonNull Context context,
             boolean enabled) {
         super(context, enabled);
-        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
-        mAppOpsManager = context.getSystemService(AppOpsManager.class);
         mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
-        mIPackageManager = AppGlobals.getPackageManager();
-        mUserManager = context.getSystemService(UserManager.class);
-        mPackageManager = context.getPackageManager();
 
-        setRestriction(enabled);
+        onAdvancedProtectionChanged(enabled);
     }
 
     @NonNull
@@ -76,7 +55,8 @@
         return true;
     }
 
-    private void setRestriction(boolean enabled) {
+    @Override
+    public void onAdvancedProtectionChanged(boolean enabled) {
         if (enabled) {
             Slog.d(TAG, "Setting DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY restriction");
             mDevicePolicyManager.addUserRestrictionGlobally(ADVANCED_PROTECTION_SYSTEM_ENTITY,
@@ -87,36 +67,4 @@
                     UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY);
         }
     }
-
-    @Override
-    public void onAdvancedProtectionChanged(boolean enabled) {
-        setRestriction(enabled);
-        if (enabled) return;
-
-        // Leave OP_REQUEST_INSTALL_PACKAGES disabled when APM is disabled.
-        Slog.d(TAG, "Setting all OP_REQUEST_INSTALL_PACKAGES to MODE_ERRORED");
-        for (UserInfo userInfo : mUserManager.getAliveUsers()) {
-            try {
-                final String[] packagesWithRequestInstallPermission = mIPackageManager
-                        .getAppOpPermissionPackages(
-                                Manifest.permission.REQUEST_INSTALL_PACKAGES, userInfo.id);
-                for (String packageName : packagesWithRequestInstallPermission) {
-                    try {
-                        int uid = mPackageManager.getPackageUidAsUser(packageName, userInfo.id);
-                        boolean isCallerInstrumented = mActivityManagerInternal
-                                .getInstrumentationSourceUid(uid) != Process.INVALID_UID;
-                        if (!isCallerInstrumented) {
-                            mAppOpsManager.setMode(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES, uid,
-                                    packageName, AppOpsManager.MODE_ERRORED);
-                        }
-                    } catch (PackageManager.NameNotFoundException e) {
-                        Slog.e(TAG, "Couldn't retrieve uid for a package: " + e);
-                    }
-                }
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Couldn't retrieve packages with REQUEST_INSTALL_PACKAGES."
-                        + " getAppOpPermissionPackages() threw the following exception: " + e);
-            }
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 3f814f9..417d6a5 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -110,6 +110,7 @@
 import com.android.server.LocalServices;
 import com.android.server.apphibernation.AppHibernationManagerInternal;
 import com.android.server.apphibernation.AppHibernationService;
+import com.android.window.flags.Flags;
 
 import java.util.ArrayList;
 import java.util.concurrent.TimeUnit;
@@ -778,11 +779,12 @@
      */
     private void updateSplitPairLaunches(@NonNull TransitionInfo info) {
         final Task launchedActivityTask = info.mLastLaunchedActivity.getTask();
-        final Task adjacentToLaunchedTask = launchedActivityTask.getAdjacentTask();
-        if (adjacentToLaunchedTask == null) {
+        final Task launchedSplitRootTask = launchedActivityTask.getTaskWithAdjacent();
+        if (launchedSplitRootTask == null) {
             // Not a part of a split pair
             return;
         }
+
         for (int i = mTransitionInfoList.size() - 1; i >= 0; i--) {
             final TransitionInfo otherInfo = mTransitionInfoList.get(i);
             if (otherInfo == info) {
@@ -790,7 +792,15 @@
             }
             final Task otherTask = otherInfo.mLastLaunchedActivity.getTask();
             // The adjacent task is the split root in which activities are started
-            if (otherTask.isDescendantOf(adjacentToLaunchedTask)) {
+            final boolean isDescendantOfAdjacent;
+            if (Flags.allowMultipleAdjacentTaskFragments()) {
+                isDescendantOfAdjacent = launchedSplitRootTask.forOtherAdjacentTasks(
+                        otherTask::isDescendantOf);
+            } else {
+                isDescendantOfAdjacent = otherTask.isDescendantOf(
+                        launchedSplitRootTask.getAdjacentTask());
+            }
+            if (isDescendantOfAdjacent) {
                 if (DEBUG_METRICS) {
                     Slog.i(TAG, "Found adjacent tasks t1=" + launchedActivityTask.mTaskId
                             + " t2=" + otherTask.mTaskId);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 3467f94..db9e19a 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2406,9 +2406,8 @@
             return false;
         }
 
-        final TaskSnapshot snapshot =
-                mWmService.mTaskSnapshotController.getSnapshot(task.mTaskId, task.mUserId,
-                        false /* restoreFromDisk */, false /* isLowResolution */);
+        final TaskSnapshot snapshot = mWmService.mTaskSnapshotController.getSnapshot(task.mTaskId,
+                false /* isLowResolution */);
         final int type = getStartingWindowType(newTask, taskSwitch, processRunning,
                 allowTaskSnapshot, activityCreated, activityAllDrawn, snapshot);
 
@@ -2650,7 +2649,8 @@
                 // Skip copy splash screen to client if it was resized, or the starting data already
                 // requested to be removed after transaction commit.
                 || (mStartingData != null && (mStartingData.mResizedFromTransfer
-                        || mStartingData.mRemoveAfterTransaction != AFTER_TRANSACTION_IDLE))
+                        || mStartingData.mRemoveAfterTransaction
+                        == AFTER_TRANSACTION_REMOVE_DIRECTLY))
                 || isRelaunching()) {
             return false;
         }
@@ -3212,8 +3212,7 @@
      * will be ignored.
      */
     boolean isUniversalResizeable() {
-        final boolean isLargeScreen = mDisplayContent != null && mDisplayContent.getConfiguration()
-                .smallestScreenWidthDp >= WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP
+        final boolean isLargeScreen = mDisplayContent != null && mDisplayContent.isLargeScreen()
                 && mDisplayContent.getIgnoreOrientationRequest();
         if (!canBeUniversalResizeable(info.applicationInfo, mWmService, isLargeScreen,
                 true /* forActivity */)) {
@@ -4585,6 +4584,19 @@
         }
     }
 
+    /**
+     * Returns {@code true} if the requested orientation of this activity is the same as the
+     * resolved orientation of the from activity.
+     */
+    private boolean isStartingOrientationCompatible(@NonNull ActivityRecord fromActivity) {
+        final int fromOrientation = fromActivity.getConfiguration().orientation;
+        final int requestedOrientation = getRequestedConfigurationOrientation();
+        if (requestedOrientation == ORIENTATION_UNDEFINED) {
+            return fromOrientation == getConfiguration().orientation;
+        }
+        return fromOrientation == requestedOrientation;
+    }
+
     private boolean transferStartingWindow(@NonNull ActivityRecord fromActivity) {
         final WindowState tStartingWindow = fromActivity.mStartingWindow;
         if (tStartingWindow != null && fromActivity.mStartingSurface != null) {
@@ -4604,13 +4616,7 @@
             }
             // Do not transfer if the orientation doesn't match, redraw starting window while it is
             // on top will cause flicker.
-            final int fromOrientation = fromActivity.getConfiguration().orientation;
-            final int requestedOrientation = getRequestedConfigurationOrientation();
-            if (requestedOrientation == ORIENTATION_UNDEFINED) {
-                if (fromOrientation != getConfiguration().orientation) {
-                    return false;
-                }
-            } else if (fromOrientation != requestedOrientation) {
+            if (!isStartingOrientationCompatible(fromActivity)) {
                 return false;
             }
 
@@ -4708,6 +4714,11 @@
             }
             return true;
         } else if (fromActivity.mStartingData != null) {
+            if (fromActivity.mStartingData instanceof SnapshotStartingData
+                    && !isStartingOrientationCompatible(fromActivity)) {
+                // Do not transfer because the snapshot will be distorted in different orientation.
+                return false;
+            }
             // The previous app was getting ready to show a
             // starting window, but hasn't yet done so.  Steal it!
             ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
@@ -5408,10 +5419,16 @@
     }
 
     void setDeferHidingClient() {
+        if (Flags.removeDeferHidingClient()) {
+            return;
+        }
         mDeferHidingClient = true;
     }
 
     void clearDeferHidingClient() {
+        if (Flags.removeDeferHidingClient()) {
+            return;
+        }
         if (!mDeferHidingClient) return;
         mDeferHidingClient = false;
         if (!mVisibleRequested) {
@@ -7141,9 +7158,11 @@
 
     @Override
     void setClientVisible(boolean clientVisible) {
-        // TODO(shell-transitions): Remove mDeferHidingClient once everything is shell-transitions.
-        //                          pip activities should just remain in clientVisible.
-        if (!clientVisible && mDeferHidingClient) return;
+        if (!Flags.removeDeferHidingClient()) {
+            // TODO(shell-transitions): Remove mDeferHidingClient once everything is
+            //  shell-transitions. pip activities should just remain in clientVisible.
+            if (!clientVisible && mDeferHidingClient) return;
+        }
         super.setClientVisible(clientVisible);
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java b/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
index 1208b6ef..08ceb61 100644
--- a/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
+++ b/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
@@ -142,6 +142,8 @@
     /** Used by {@link ActivityRecord#dump}. */
     @Override
     public String toString() {
-        return String.valueOf(mConnections);
+        synchronized (mActivity) {
+            return String.valueOf(mConnections);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/wm/ActivitySnapshotController.java b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
index 24ed1bb..9aaa0e1 100644
--- a/services/core/java/com/android/server/wm/ActivitySnapshotController.java
+++ b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
@@ -18,6 +18,8 @@
 
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 
+import static com.android.server.wm.SnapshotPersistQueue.MAX_STORE_QUEUE_DEPTH;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
@@ -147,7 +149,8 @@
         for (int i = activities.length - 1; i >= 0; --i) {
             fileId ^= getSystemHashCode(activities[i]);
         }
-        return tmpUsf.mFileId == fileId ? mCache.getSnapshot(tmpUsf.mActivityIds.get(0)) : null;
+        return tmpUsf.mFileId == fileId
+                ? mCache.getSnapshotInner(tmpUsf.mActivityIds.get(0)) : null;
     }
 
     private void cleanUpUserFiles(int userId) {
@@ -343,6 +346,11 @@
         if (DEBUG) {
             Slog.d(TAG, "ActivitySnapshotController#recordSnapshot " + activity);
         }
+        if (mPersister.mSnapshotPersistQueue.peekWriteQueueSize() >= MAX_STORE_QUEUE_DEPTH
+                || mPersister.mSnapshotPersistQueue.peekQueueSize() > MAX_PERSIST_SNAPSHOT_COUNT) {
+            Slog.w(TAG, "Skipping recording activity snapshot, too many requests!");
+            return;
+        }
         final int size = activity.size();
         final int[] mixedCode = new int[size];
         if (size == 1) {
@@ -432,7 +440,7 @@
             addBelowActivityIfExist(ar, mPendingLoadActivity, false, "load-snapshot");
         } else {
             // remove the snapshot for the one below close
-            addBelowActivityIfExist(ar, mPendingRemoveActivity, true, "remove-snapshot");
+            addBelowActivityIfExist(ar, mPendingRemoveActivity, false, "remove-snapshot");
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 90d3834..2781592 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -27,6 +27,7 @@
 import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
 import static android.app.ActivityManager.START_SUCCESS;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
+import static android.app.ActivityManager.isStartResultSuccessful;
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
 import static android.app.PendingIntent.FLAG_ONE_SHOT;
@@ -891,7 +892,10 @@
                 final ActivityOptions originalOptions = mRequest.activityOptions != null
                         ? mRequest.activityOptions.getOriginalOptions() : null;
                 // Only track the launch time of activity that will be resumed.
-                launchingRecord = mDoResume ? mLastStartActivityRecord : null;
+                if (mDoResume || (isStartResultSuccessful(res)
+                        && mLastStartActivityRecord.getTask().isVisibleRequested())) {
+                    launchingRecord = mLastStartActivityRecord;
+                }
                 // If the new record is the one that started, a new activity has created.
                 final boolean newActivityCreated = mStartActivity == launchingRecord;
                 // Notify ActivityMetricsLogger that the activity has launched.
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index afa7ea1..5eee8ec 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -3996,15 +3996,14 @@
             }
             // Try to load snapshot from cache first, and add reference if the snapshot is in cache.
             final TaskSnapshot snapshot = mWindowManager.mTaskSnapshotController.getSnapshot(taskId,
-                    task.mUserId, false /* restoreFromDisk */, isLowResolution);
+                    isLowResolution, usage);
             if (snapshot != null) {
-                snapshot.addReference(usage);
                 return snapshot;
             }
         }
         // Don't call this while holding the lock as this operation might hit the disk.
-        return mWindowManager.mTaskSnapshotController.getSnapshot(taskId,
-                task.mUserId, true /* restoreFromDisk */, isLowResolution);
+        return mWindowManager.mTaskSnapshotController.getSnapshotFromDisk(taskId,
+                task.mUserId,  isLowResolution, usage);
     }
 
     @Override
@@ -4020,10 +4019,15 @@
                     Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
                     return null;
                 }
+                final TaskSnapshot snapshot = mWindowManager.mTaskSnapshotController.getSnapshot(
+                        taskId, isLowResolution, TaskSnapshot.REFERENCE_WRITE_TO_PARCEL);
+                if (snapshot != null) {
+                    return snapshot;
+                }
             }
             // Don't call this while holding the lock as this operation might hit the disk.
-            return mWindowManager.mTaskSnapshotController.getSnapshot(taskId,
-                    task.mUserId, true /* restoreFromDisk */, isLowResolution);
+            return mWindowManager.mTaskSnapshotController.getSnapshotFromDisk(taskId,
+                    task.mUserId, isLowResolution, TaskSnapshot.REFERENCE_WRITE_TO_PARCEL);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 741eefa..492d84f 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -996,8 +996,7 @@
                 // If the current window container is a task with adjacent task set, the both
                 // adjacent tasks will be opened or closed together. To get their opening or
                 // closing animation target independently, skip promoting their animation targets.
-                if (current.asTask() != null
-                        && current.asTask().getAdjacentTask() != null) {
+                if (current.asTask() != null && current.asTask().hasAdjacentTask()) {
                     canPromote = false;
                 }
 
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 3968b52..e9e3c9e 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -2251,8 +2251,7 @@
         if (w.asTask() != null) {
             final Task task = w.asTask();
             snapshot = task.mRootWindowContainer.mWindowManager.mTaskSnapshotController.getSnapshot(
-                    task.mTaskId, task.mUserId, false /* restoreFromDisk */,
-                    false /* isLowResolution */);
+                    task.mTaskId, false /* isLowResolution */);
         } else {
             ActivityRecord ar = w.asActivityRecord();
             if (ar == null && w.asTaskFragment() != null) {
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index 6ccceb9..8eccffd 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -473,15 +473,17 @@
             case RECORD_CONTENT_TASK:
                 // Given the WindowToken of the region to record, retrieve the associated
                 // SurfaceControl.
-                if (tokenToRecord == null) {
+                final WindowContainer wc = tokenToRecord != null
+                        ? WindowContainer.fromBinder(tokenToRecord) : null;
+                if (wc == null) {
                     handleStartRecordingFailed();
                     ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
-                            "Content Recording: Unable to start recording due to null token for "
-                                    + "display %d",
+                            "Content Recording: Unable to start recording due to null token or " +
+                                    "null window container for " + "display %d",
                             mDisplayContent.getDisplayId());
                     return null;
                 }
-                Task taskToRecord = WindowContainer.fromBinder(tokenToRecord).asTask();
+                final Task taskToRecord = wc.asTask();
                 if (taskToRecord == null) {
                     handleStartRecordingFailed();
                     ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0b66158..f808661 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -260,6 +260,7 @@
 import com.android.server.wm.utils.RegionUtils;
 import com.android.server.wm.utils.RotationCache;
 import com.android.server.wm.utils.WmDisplayCutout;
+import com.android.window.flags.Flags;
 
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -438,6 +439,10 @@
      */
     private boolean mSandboxDisplayApis = true;
 
+    /** Whether {@link #setIgnoreOrientationRequest} is called to override the default policy. */
+    @VisibleForTesting
+    boolean mHasSetIgnoreOrientationRequest;
+
     /**
      * Overridden display density for current user. Initialized with {@link #mInitialDisplayDensity}
      * but can be set from Settings or via shell command "adb shell wm density".
@@ -1390,11 +1395,16 @@
         mTokenMap.put(binder, token);
 
         if (token.asActivityRecord() == null) {
-            // Set displayContent for non-app token to prevent same token will add twice after
-            // onDisplayChanged.
-            // TODO: Check if it's fine that super.onDisplayChanged of WindowToken
-            //  (WindowsContainer#onDisplayChanged) may skipped when token.mDisplayContent assigned.
-            token.mDisplayContent = this;
+            // Setting the mDisplayContent to the token is not needed: it is done by da.addChild
+            // below, that also calls onDisplayChanged once moved.
+            if (!Flags.reparentWindowTokenApi()) {
+                // Set displayContent for non-app token to prevent same token will add twice after
+                // onDisplayChanged.
+                // TODO: Check if it's fine that super.onDisplayChanged of WindowToken
+                //  (WindowsContainer#onDisplayChanged) may skipped when token.mDisplayContent
+                //  assigned.
+                token.mDisplayContent = this;
+            }
             // Add non-app token to container hierarchy on the display. App tokens are added through
             // the parent container managing them (e.g. Tasks).
             final DisplayArea.Tokens da = findAreaForToken(token).asTokens();
@@ -6716,8 +6726,25 @@
         return mDisplayPolicy.getSystemUiContext();
     }
 
+    /** Returns {@code} true if the smallest screen width dp >= 600. */
+    boolean isLargeScreen() {
+        return getConfiguration().smallestScreenWidthDp
+                >= WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
+    }
+
+    @Override
+    boolean getIgnoreOrientationRequest() {
+        if (mHasSetIgnoreOrientationRequest
+                || !com.android.window.flags.Flags.universalResizableByDefault()) {
+            return super.getIgnoreOrientationRequest();
+        }
+        // Large screen (sw >= 600dp) ignores orientation request by default.
+        return isLargeScreen() && !mWmService.isIgnoreOrientationRequestDisabled();
+    }
+
     @Override
     boolean setIgnoreOrientationRequest(boolean ignoreOrientationRequest) {
+        mHasSetIgnoreOrientationRequest = true;
         if (mSetIgnoreOrientationRequest == ignoreOrientationRequest) return false;
         final boolean rotationChanged = super.setIgnoreOrientationRequest(ignoreOrientationRequest);
         mWmService.mDisplayWindowSettings.setIgnoreOrientationRequest(
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 659bb67..01e00e9 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -2485,7 +2485,7 @@
         final TaskDisplayArea defaultTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
         final boolean adjacentTasksVisible =
                 defaultTaskDisplayArea.getRootTask(task -> task.isVisible()
-                        && task.getTopLeafTask().getAdjacentTask() != null)
+                        && task.getTopLeafTask().hasAdjacentTask())
                         != null;
         final Task topFreeformTask = defaultTaskDisplayArea
                 .getTopRootTaskInWindowingMode(WINDOWING_MODE_FREEFORM);
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index f6d05d0..f0ba822 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -374,9 +374,9 @@
         final DisplayInfo displayInfo = dc.getDisplayInfo();
         final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
 
-        final boolean ignoreOrientationRequest = settings.mIgnoreOrientationRequest != null
-                ? settings.mIgnoreOrientationRequest : false;
-        dc.setIgnoreOrientationRequest(ignoreOrientationRequest);
+        if (settings.mIgnoreOrientationRequest != null) {
+            dc.setIgnoreOrientationRequest(settings.mIgnoreOrientationRequest);
+        }
 
         dc.getDisplayRotation().resetAllowAllRotations();
     }
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 4230cd8..cba606c 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -324,7 +324,8 @@
             if (target != imeControlTarget) {
                 // TODO(b/353463205): check if fromUser=false is correct here
                 boolean imeVisible = target.isRequestedVisible(WindowInsets.Type.ime());
-                ImeTracker.Token statsToken = ImeTracker.forLogging().onStart(ImeTracker.TYPE_HIDE,
+                ImeTracker.Token statsToken = ImeTracker.forLogging().onStart(
+                        imeVisible ? ImeTracker.TYPE_SHOW : ImeTracker.TYPE_HIDE,
                         ImeTracker.ORIGIN_SERVER,
                         imeVisible ? SoftInputShowHideReason.SHOW_INPUT_TARGET_CHANGED
                                 : SoftInputShowHideReason.HIDE_INPUT_TARGET_CHANGED,
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 46312af..3d28685 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -156,6 +156,7 @@
 import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.utils.Slogf;
 import com.android.server.wm.utils.RegionUtils;
+import com.android.window.flags.Flags;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -262,6 +263,7 @@
     int mCurrentUser;
     /** Root task id of the front root task when user switched, indexed by userId. */
     SparseIntArray mUserRootTaskInFront = new SparseIntArray(2);
+    SparseArray<IntArray> mUserVisibleRootTasks = new SparseArray<>();
 
     /**
      * A list of tokens that cause the top activity to be put to sleep.
@@ -1794,12 +1796,24 @@
                     activityAssistInfos.clear();
                     activityAssistInfos.add(new ActivityAssistInfo(top));
                     // Check if the activity on the split screen.
-                    final Task adjacentTask = top.getTask().getAdjacentTask();
-                    if (adjacentTask != null) {
-                        final ActivityRecord adjacentActivityRecord =
-                                adjacentTask.getTopNonFinishingActivity();
-                        if (adjacentActivityRecord != null) {
-                            activityAssistInfos.add(new ActivityAssistInfo(adjacentActivityRecord));
+                    if (Flags.allowMultipleAdjacentTaskFragments()) {
+                        top.getTask().forOtherAdjacentTasks(task -> {
+                            final ActivityRecord adjacentActivityRecord =
+                                    task.getTopNonFinishingActivity();
+                            if (adjacentActivityRecord != null) {
+                                activityAssistInfos.add(
+                                        new ActivityAssistInfo(adjacentActivityRecord));
+                            }
+                        });
+                    } else {
+                        final Task adjacentTask = top.getTask().getAdjacentTask();
+                        if (adjacentTask != null) {
+                            final ActivityRecord adjacentActivityRecord =
+                                    adjacentTask.getTopNonFinishingActivity();
+                            if (adjacentActivityRecord != null) {
+                                activityAssistInfos.add(
+                                        new ActivityAssistInfo(adjacentActivityRecord));
+                            }
                         }
                     }
                     if (rootTask == topFocusedRootTask) {
@@ -1924,7 +1938,18 @@
         // appropriate.
         removeRootTasksInWindowingModes(WINDOWING_MODE_PINNED);
 
-        mUserRootTaskInFront.put(mCurrentUser, focusRootTaskId);
+        if (Flags.enableTopVisibleRootTaskPerUserTracking()) {
+            final IntArray visibleRootTasks = new IntArray();
+            forAllRootTasks(rootTask -> {
+                if (mCurrentUser == rootTask.mUserId && rootTask.isVisibleRequested()) {
+                    visibleRootTasks.add(rootTask.getRootTaskId());
+                }
+            }, /* traverseTopToBottom */ false);
+            mUserVisibleRootTasks.put(mCurrentUser, visibleRootTasks);
+        } else {
+            mUserRootTaskInFront.put(mCurrentUser, focusRootTaskId);
+        }
+
         mCurrentUser = userId;
 
         mTaskSupervisor.mStartingUsers.add(uss);
@@ -1937,22 +1962,60 @@
             Slog.i(TAG, "Persisting top task because it belongs to an always-visible user");
             // For a normal user-switch, we will restore the new user's task. But if the pre-switch
             // top task is an always-visible (Communal) one, keep it even after the switch.
-            mUserRootTaskInFront.put(mCurrentUser, focusRootTaskId);
+            if (Flags.enableTopVisibleRootTaskPerUserTracking()) {
+                final IntArray rootTasks = mUserVisibleRootTasks.get(mCurrentUser);
+                rootTasks.add(focusRootTaskId);
+                mUserVisibleRootTasks.put(mCurrentUser, rootTasks);
+            } else {
+                mUserRootTaskInFront.put(mCurrentUser, focusRootTaskId);
+            }
+
         }
 
         final int restoreRootTaskId = mUserRootTaskInFront.get(userId);
+        final IntArray rootTaskIdsToRestore = mUserVisibleRootTasks.get(userId);
+        boolean homeInFront = false;
+        if (Flags.enableTopVisibleRootTaskPerUserTracking()) {
+            if (rootTaskIdsToRestore == null) {
+                // If there are no root tasks saved, try restore id 0 which should create and launch
+                // the home task.
+                handleRootTaskLaunchOnUserSwitch(/* restoreRootTaskId */INVALID_TASK_ID);
+                homeInFront = true;
+            } else {
+                for (int i = 0; i < rootTaskIdsToRestore.size(); i++) {
+                    handleRootTaskLaunchOnUserSwitch(rootTaskIdsToRestore.get(i));
+                }
+                // Check if the top task is type home
+                if (rootTaskIdsToRestore.size() > 0) {
+                    final int topRootTaskId = rootTaskIdsToRestore.get(
+                            rootTaskIdsToRestore.size() - 1);
+                    homeInFront = isHomeTask(topRootTaskId);
+                }
+            }
+        } else {
+            handleRootTaskLaunchOnUserSwitch(restoreRootTaskId);
+            // Check if the top task is type home
+            homeInFront = isHomeTask(restoreRootTaskId);
+        }
+        return homeInFront;
+    }
+
+    private boolean isHomeTask(int taskId) {
+        final Task rootTask = getRootTask(taskId);
+        return rootTask != null && rootTask.isActivityTypeHome();
+    }
+
+    private void handleRootTaskLaunchOnUserSwitch(int restoreRootTaskId) {
         Task rootTask = getRootTask(restoreRootTaskId);
         if (rootTask == null) {
             rootTask = getDefaultTaskDisplayArea().getOrCreateRootHomeTask();
         }
-        final boolean homeInFront = rootTask.isActivityTypeHome();
         if (rootTask.isOnHomeDisplay()) {
             rootTask.moveToFront("switchUserOnHomeDisplay");
         } else {
             // Root task was moved to another display while user was swapped out.
             resumeHomeActivity(null, "switchUserOnOtherDisplay", getDefaultTaskDisplayArea());
         }
-        return homeInFront;
     }
 
     /** Returns whether the given user is to be always-visible (e.g. a communal profile). */
@@ -1963,7 +2026,11 @@
     }
 
     void removeUser(int userId) {
-        mUserRootTaskInFront.delete(userId);
+        if (Flags.enableTopVisibleRootTaskPerUserTracking()) {
+            mUserVisibleRootTasks.delete(userId);
+        } else {
+            mUserRootTaskInFront.delete(userId);
+        }
     }
 
     /**
@@ -1976,7 +2043,13 @@
                 rootTask = getDefaultTaskDisplayArea().getOrCreateRootHomeTask();
             }
 
-            mUserRootTaskInFront.put(userId, rootTask.getRootTaskId());
+            if (Flags.enableTopVisibleRootTaskPerUserTracking()) {
+                final IntArray rootTasks = mUserVisibleRootTasks.get(userId, new IntArray());
+                rootTasks.add(rootTask.getRootTaskId());
+                mUserVisibleRootTasks.put(userId, rootTasks);
+            } else {
+                mUserRootTaskInFront.put(userId, rootTask.getRootTaskId());
+            }
         }
     }
 
@@ -2124,7 +2197,7 @@
                     if (!tf.isOrganizedTaskFragment()) {
                         return;
                     }
-                    tf.resetAdjacentTaskFragment();
+                    tf.clearAdjacentTaskFragments();
                     tf.setCompanionTaskFragment(null /* companionTaskFragment */);
                     tf.setAnimationParams(TaskFragmentAnimationParams.DEFAULT);
                     if (tf.getTopNonFinishingActivity() != null) {
diff --git a/services/core/java/com/android/server/wm/SnapshotCache.java b/services/core/java/com/android/server/wm/SnapshotCache.java
index 1e6ee7d..9812a88 100644
--- a/services/core/java/com/android/server/wm/SnapshotCache.java
+++ b/services/core/java/com/android/server/wm/SnapshotCache.java
@@ -51,7 +51,7 @@
     }
 
     @Nullable
-    final TaskSnapshot getSnapshot(Integer id) {
+    final TaskSnapshot getSnapshotInner(Integer id) {
         synchronized (mLock) {
             // Try the running cache.
             final CacheEntry entry = mRunningCache.get(id);
diff --git a/services/core/java/com/android/server/wm/SnapshotController.java b/services/core/java/com/android/server/wm/SnapshotController.java
index 3ee2e60..dcdffa4 100644
--- a/services/core/java/com/android/server/wm/SnapshotController.java
+++ b/services/core/java/com/android/server/wm/SnapshotController.java
@@ -202,7 +202,7 @@
             final Task task = wc.asTask();
             if (task != null && wc.isVisibleRequested() && !task.inPinnedWindowingMode()) {
                 final TaskSnapshot snapshot = mTaskSnapshotController.getSnapshot(task.mTaskId,
-                        task.mUserId, false /* restoreFromDisk */, false /* isLowResolution */);
+                        false /* isLowResolution */);
                 if (snapshot != null) {
                     mTaskSnapshotController.removeAndDeleteSnapshot(task.mTaskId, task.mUserId);
                 }
diff --git a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
index 8b63ecf7..a545454 100644
--- a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
+++ b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
@@ -50,7 +50,7 @@
 class SnapshotPersistQueue {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskSnapshotPersister" : TAG_WM;
     private static final long DELAY_MS = 100;
-    private static final int MAX_STORE_QUEUE_DEPTH = 2;
+    static final int MAX_STORE_QUEUE_DEPTH = 2;
     private static final int COMPRESS_QUALITY = 95;
 
     @GuardedBy("mLock")
@@ -154,7 +154,12 @@
         }
     }
 
-    @VisibleForTesting
+    int peekWriteQueueSize() {
+        synchronized (mLock) {
+            return mStoreQueueItems.size();
+        }
+    }
+
     int peekQueueSize() {
         synchronized (mLock) {
             return mWriteQueue.size();
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 810aa04..76d8861 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -2500,20 +2500,79 @@
         return parentTask == null ? null : parentTask.getCreatedByOrganizerTask();
     }
 
-    /** @return the first adjacent task of this task or its parent. */
+    /** @deprecated b/373709676 replace with {@link #forOtherAdjacentTasks(Consumer)} ()}. */
+    @Deprecated
     @Nullable
     Task getAdjacentTask() {
-        final TaskFragment adjacentTaskFragment = getAdjacentTaskFragment();
-        if (adjacentTaskFragment != null && adjacentTaskFragment.asTask() != null) {
-            return adjacentTaskFragment.asTask();
+        if (Flags.allowMultipleAdjacentTaskFragments()) {
+            throw new IllegalStateException("allowMultipleAdjacentTaskFragments is enabled. "
+                    + "Use #forOtherAdjacentTasks instead");
         }
+        final Task taskWithAdjacent = getTaskWithAdjacent();
+        if (taskWithAdjacent == null) {
+            return null;
+        }
+        return taskWithAdjacent.getAdjacentTaskFragment().asTask();
+    }
 
+    /** Finds the first Task parent (or itself) that has adjacent. */
+    @Nullable
+    Task getTaskWithAdjacent() {
+        if (hasAdjacentTaskFragment()) {
+            return this;
+        }
         final WindowContainer parent = getParent();
         if (parent == null || parent.asTask() == null) {
             return null;
         }
+        return parent.asTask().getTaskWithAdjacent();
+    }
 
-        return parent.asTask().getAdjacentTask();
+    /** Returns true if this or its parent has adjacent Task. */
+    boolean hasAdjacentTask() {
+        return getTaskWithAdjacent() != null;
+    }
+
+    /**
+     * Finds the first Task parent (or itself) that has adjacent. Runs callback on all the adjacent
+     * Tasks. The invoke order is not guaranteed.
+     */
+    void forOtherAdjacentTasks(@NonNull Consumer<Task> callback) {
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            throw new IllegalStateException("allowMultipleAdjacentTaskFragments is not enabled. "
+                    + "Use #getAdjacentTask instead");
+        }
+
+        final Task taskWithAdjacent = getTaskWithAdjacent();
+        if (taskWithAdjacent == null) {
+            return;
+        }
+        final AdjacentSet adjacentTasks = taskWithAdjacent.getAdjacentTaskFragments();
+        adjacentTasks.forAllTaskFragments(tf -> {
+            // We don't support Task adjacent to non-Task TaskFragment.
+            callback.accept(tf.asTask());
+        }, taskWithAdjacent /* exclude */);
+    }
+
+    /**
+     * Finds the first Task parent (or itself) that has adjacent. Runs callback on all the adjacent
+     * Tasks. Returns early if callback returns true on any of them. The invoke order is not
+     * guaranteed.
+     */
+    boolean forOtherAdjacentTasks(@NonNull Predicate<Task> callback) {
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            throw new IllegalStateException("allowMultipleAdjacentTaskFragments is not enabled. "
+                    + "Use getAdjacentTask instead");
+        }
+        final Task taskWithAdjacent = getTaskWithAdjacent();
+        if (taskWithAdjacent == null) {
+            return false;
+        }
+        final AdjacentSet adjacentTasks = taskWithAdjacent.getAdjacentTaskFragments();
+        return adjacentTasks.forAllTaskFragments(tf -> {
+            // We don't support Task adjacent to non-Task TaskFragment.
+            return callback.test(tf.asTask());
+        }, taskWithAdjacent /* exclude */);
     }
 
     // TODO(task-merge): Figure out what's the right thing to do for places that used it.
@@ -2907,7 +2966,7 @@
             Rect outSurfaceInsets) {
         // If this task has its adjacent task, it means they should animate together. Use display
         // bounds for them could move same as full screen task.
-        if (getAdjacentTask() != null) {
+        if (hasAdjacentTask()) {
             super.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
             return;
         }
@@ -3864,6 +3923,9 @@
         if (mLaunchAdjacentDisabled) {
             pw.println(prefix + "mLaunchAdjacentDisabled=true");
         }
+        if (mReparentLeafTaskIfRelaunch) {
+            pw.println(prefix + "mReparentLeafTaskIfRelaunch=true");
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 2c71c1a..9564c59 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -31,6 +31,7 @@
 import static android.view.Display.INVALID_DISPLAY;
 
 import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_ORIENTATION;
+import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_TASKS;
 import static com.android.server.wm.ActivityRecord.State.RESUMED;
 import static com.android.server.wm.ActivityTaskManagerService.TAG_ROOT_TASK;
 import static com.android.server.wm.DisplayContent.alwaysCreateRootTask;
@@ -60,6 +61,7 @@
 import com.android.internal.util.function.pooled.PooledPredicate;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.wm.LaunchParamsController.LaunchParams;
+import com.android.window.flags.Flags;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -918,6 +920,10 @@
                 if (candidateTask.getParent() == null) {
                     addChild(candidateTask, position);
                 } else {
+                    if (candidateTask.getRootTask().mReparentLeafTaskIfRelaunch) {
+                        ProtoLog.d(WM_DEBUG_TASKS, "Reparenting to display area on relaunch: "
+                                + "rootTaskId=%d toTop=%b", candidateTask.mTaskId, onTop);
+                    }
                     candidateTask.reparent(this, onTop);
                 }
             }
@@ -1083,8 +1089,19 @@
         // Use launch-adjacent-flag-root if launching with launch-adjacent flag.
         if ((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0
                 && mLaunchAdjacentFlagRootTask != null) {
-            final Task launchAdjacentRootAdjacentTask =
-                    mLaunchAdjacentFlagRootTask.getAdjacentTask();
+            final Task launchAdjacentRootAdjacentTask;
+            if (Flags.allowMultipleAdjacentTaskFragments()) {
+                final Task[] tmpTask = new Task[1];
+                mLaunchAdjacentFlagRootTask.forOtherAdjacentTasks(task -> {
+                    // TODO(b/382208145): enable FLAG_ACTIVITY_LAUNCH_ADJACENT for 3+.
+                    // Find the first adjacent for now.
+                    tmpTask[0] = task;
+                    return true;
+                });
+                launchAdjacentRootAdjacentTask = tmpTask[0];
+            } else {
+                launchAdjacentRootAdjacentTask = mLaunchAdjacentFlagRootTask.getAdjacentTask();
+            }
             if (sourceTask != null && (sourceTask == candidateTask
                     || sourceTask.topRunningActivity() == null)) {
                 // Do nothing when task that is getting opened is same as the source or when
@@ -1109,15 +1126,26 @@
         for (int i = mLaunchRootTasks.size() - 1; i >= 0; --i) {
             if (mLaunchRootTasks.get(i).contains(windowingMode, activityType)) {
                 final Task launchRootTask = mLaunchRootTasks.get(i).task;
-                final Task adjacentRootTask = launchRootTask != null
-                        ? launchRootTask.getAdjacentTask() : null;
-                if (sourceTask != null && adjacentRootTask != null
-                        && (sourceTask == adjacentRootTask
-                        || sourceTask.isDescendantOf(adjacentRootTask))) {
-                    return adjacentRootTask;
-                } else {
+                if (launchRootTask == null || sourceTask == null) {
                     return launchRootTask;
                 }
+                if (!Flags.allowMultipleAdjacentTaskFragments()) {
+                    final Task adjacentRootTask = launchRootTask.getAdjacentTask();
+                    if (adjacentRootTask != null && (sourceTask == adjacentRootTask
+                            || sourceTask.isDescendantOf(adjacentRootTask))) {
+                        return adjacentRootTask;
+                    }
+                    return launchRootTask;
+                }
+                final Task[] adjacentRootTask = new Task[1];
+                launchRootTask.forOtherAdjacentTasks(task -> {
+                    if (sourceTask == task || sourceTask.isDescendantOf(task)) {
+                        adjacentRootTask[0] = task;
+                        return true;
+                    }
+                    return false;
+                });
+                return adjacentRootTask[0] != null ? adjacentRootTask[0] : launchRootTask;
             }
         }
 
@@ -1128,12 +1156,31 @@
                 // A pinned task relaunching should be handled by its task organizer. Skip fallback
                 // launch target of a pinned task from source task.
                 || candidateTask.getWindowingMode() != WINDOWING_MODE_PINNED)) {
-            final Task adjacentTarget = sourceTask.getAdjacentTask();
-            if (adjacentTarget != null) {
-                if (candidateTask != null
-                        && (candidateTask == adjacentTarget
-                        || candidateTask.isDescendantOf(adjacentTarget))) {
-                    return adjacentTarget;
+            final Task taskWithAdjacent = sourceTask.getTaskWithAdjacent();
+            if (taskWithAdjacent != null) {
+                // Has adjacent.
+                if (candidateTask == null) {
+                    return sourceTask.getCreatedByOrganizerTask();
+                }
+                // Check if the candidate is already positioned in the adjacent Task.
+                if (Flags.allowMultipleAdjacentTaskFragments()) {
+                    final Task[] adjacentRootTask = new Task[1];
+                    sourceTask.forOtherAdjacentTasks(task -> {
+                        if (candidateTask == task || candidateTask.isDescendantOf(task)) {
+                            adjacentRootTask[0] = task;
+                            return true;
+                        }
+                        return false;
+                    });
+                    if (adjacentRootTask[0] != null) {
+                        return adjacentRootTask[0];
+                    }
+                } else {
+                    final Task adjacentTarget = taskWithAdjacent.getAdjacentTask();
+                    if (candidateTask == adjacentTarget
+                            || candidateTask.isDescendantOf(adjacentTarget)) {
+                        return adjacentTarget;
+                    }
                 }
                 return sourceTask.getCreatedByOrganizerTask();
             }
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 51b8bd1..cb6b690 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -94,6 +94,7 @@
 import android.graphics.Rect;
 import android.os.IBinder;
 import android.os.UserHandle;
+import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
@@ -239,12 +240,20 @@
     /** This task fragment will be removed when the cleanup of its children are done. */
     private boolean mIsRemovalRequested;
 
-    /** The TaskFragment that is adjacent to this one. */
+    /** @deprecated b/373709676 replace with {@link #mAdjacentTaskFragments} */
+    @Deprecated
     @Nullable
     private TaskFragment mAdjacentTaskFragment;
 
     /**
-     * Unlike the {@link mAdjacentTaskFragment}, the companion TaskFragment is not always visually
+     * The TaskFragments that are adjacent to each other, including this TaskFragment.
+     * All TaskFragments in this set share the same set instance.
+     */
+    @Nullable
+    private AdjacentSet mAdjacentTaskFragments;
+
+    /**
+     * Unlike the {@link #mAdjacentTaskFragments}, the companion TaskFragment is not always visually
      * adjacent to this one, but this TaskFragment will be removed by the organizer if the
      * companion TaskFragment is removed.
      */
@@ -442,15 +451,24 @@
         return service.mWindowOrganizerController.getTaskFragment(token);
     }
 
-    void setAdjacentTaskFragment(@Nullable TaskFragment taskFragment) {
-        if (mAdjacentTaskFragment == taskFragment) {
-            return;
-        }
-        resetAdjacentTaskFragment();
-        if (taskFragment != null) {
+    /** @deprecated b/373709676 replace with {@link #setAdjacentTaskFragments}. */
+    @Deprecated
+    void setAdjacentTaskFragment(@NonNull TaskFragment taskFragment) {
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            if (mAdjacentTaskFragment == taskFragment) {
+                return;
+            }
+            resetAdjacentTaskFragment();
             mAdjacentTaskFragment = taskFragment;
             taskFragment.setAdjacentTaskFragment(this);
+            return;
         }
+
+        setAdjacentTaskFragments(new AdjacentSet(this, taskFragment));
+    }
+
+    void setAdjacentTaskFragments(@NonNull AdjacentSet adjacentTaskFragments) {
+        adjacentTaskFragments.setAsAdjacent();
     }
 
     void setCompanionTaskFragment(@Nullable TaskFragment companionTaskFragment) {
@@ -461,7 +479,14 @@
         return mCompanionTaskFragment;
     }
 
-    void resetAdjacentTaskFragment() {
+    /** @deprecated b/373709676 replace with {@link #clearAdjacentTaskFragments()}. */
+    @Deprecated
+    private void resetAdjacentTaskFragment() {
+        if (Flags.allowMultipleAdjacentTaskFragments()) {
+            throw new IllegalStateException("resetAdjacentTaskFragment shouldn't be called when"
+                    + " allowMultipleAdjacentTaskFragments is enabled. Use either"
+                    + " #clearAdjacentTaskFragments or #removeFromAdjacentTaskFragments");
+        }
         // Reset the adjacent TaskFragment if its adjacent TaskFragment is also this TaskFragment.
         if (mAdjacentTaskFragment != null && mAdjacentTaskFragment.mAdjacentTaskFragment == this) {
             mAdjacentTaskFragment.mAdjacentTaskFragment = null;
@@ -471,6 +496,79 @@
         mDelayLastActivityRemoval = false;
     }
 
+    void clearAdjacentTaskFragments() {
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            resetAdjacentTaskFragment();
+            return;
+        }
+
+        if (mAdjacentTaskFragments != null) {
+            mAdjacentTaskFragments.clear();
+        }
+    }
+
+    void removeFromAdjacentTaskFragments() {
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            resetAdjacentTaskFragment();
+            return;
+        }
+
+        if (mAdjacentTaskFragments != null) {
+            mAdjacentTaskFragments.remove(this);
+        }
+    }
+
+    // TODO(b/373709676): update usages.
+    /** @deprecated b/373709676 replace with {@link #getAdjacentTaskFragments()}. */
+    @Deprecated
+    @Nullable
+    TaskFragment getAdjacentTaskFragment() {
+        return mAdjacentTaskFragment;
+    }
+
+    @Nullable
+    AdjacentSet getAdjacentTaskFragments() {
+        return mAdjacentTaskFragments;
+    }
+
+    /**
+     * Runs callback on all TaskFragments that are adjacent to this. The invoke order is not
+     * guaranteed.
+     */
+    void forOtherAdjacentTaskFragments(@NonNull Consumer<TaskFragment> callback) {
+        if (mAdjacentTaskFragments == null) {
+            return;
+        }
+        mAdjacentTaskFragments.forAllTaskFragments(callback, this /* exclude */);
+    }
+
+    /**
+     * Runs callback on all TaskFragments that are adjacent to this. Returns early if callback
+     * returns true on any of them. The invoke order is not guaranteed.
+     */
+    boolean forOtherAdjacentTaskFragments(@NonNull Predicate<TaskFragment> callback) {
+        if (mAdjacentTaskFragments == null) {
+            return false;
+        }
+        return mAdjacentTaskFragments.forAllTaskFragments(callback, this /* exclude */);
+    }
+
+    boolean hasAdjacentTaskFragment() {
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            return mAdjacentTaskFragment != null;
+        }
+        return mAdjacentTaskFragments != null;
+    }
+
+    boolean isAdjacentTo(@NonNull TaskFragment other) {
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            return mAdjacentTaskFragment == other;
+        }
+        return other != this
+                && mAdjacentTaskFragments != null
+                && mAdjacentTaskFragments.contains(other);
+    }
+
     void setTaskFragmentOrganizer(@NonNull TaskFragmentOrganizerToken organizer, int uid,
             @NonNull String processName) {
         mTaskFragmentOrganizer = ITaskFragmentOrganizer.Stub.asInterface(organizer.asBinder());
@@ -566,10 +664,6 @@
         return isEmbedded() && mPinned;
     }
 
-    TaskFragment getAdjacentTaskFragment() {
-        return mAdjacentTaskFragment;
-    }
-
     /** Returns the currently topmost resumed activity. */
     @Nullable
     ActivityRecord getTopResumedActivity() {
@@ -616,7 +710,7 @@
         mResumedActivity = r;
         final ActivityRecord topResumed = mTaskSupervisor.updateTopResumedActivityIfNeeded(reason);
         if (mResumedActivity != null && topResumed != null && topResumed.isEmbedded()
-                && topResumed.getTaskFragment().getAdjacentTaskFragment() == this) {
+                && topResumed.getTaskFragment().isAdjacentTo(this)) {
             // Explicitly updates the last resumed Activity if the resumed activity is
             // adjacent to the top-resumed embedded activity.
             mAtmService.setLastResumedActivityUncheckLocked(mResumedActivity, reason);
@@ -2036,7 +2130,7 @@
     private boolean shouldReportOrientationUnspecified() {
         // Apps and their containers are not allowed to specify orientation from adjacent
         // TaskFragment.
-        return getAdjacentTaskFragment() != null && isVisibleRequested();
+        return hasAdjacentTaskFragment() && isVisibleRequested();
     }
 
     @Override
@@ -3086,7 +3180,7 @@
             EventLogTags.writeWmTfRemoved(System.identityHashCode(this), getTaskId());
         }
         mIsRemovalRequested = false;
-        resetAdjacentTaskFragment();
+        removeFromAdjacentTaskFragments();
         cleanUpEmbeddedTaskFragment();
         final boolean shouldExecuteAppTransition =
                 mClearedTaskFragmentForPip && isTaskVisibleRequested();
@@ -3126,24 +3220,47 @@
             return false;
         }
 
-        final TaskFragment adjacentTf = getAdjacentTaskFragment();
-        if (adjacentTf == null) {
+        if (!hasAdjacentTaskFragment()) {
             // early return if no adjacent TF.
             return false;
         }
 
-        if (getParent().mChildren.indexOf(adjacentTf) < getParent().mChildren.indexOf(this)) {
-            // early return if this TF already has higher z-ordering.
-            return false;
+        final ArrayList<WindowContainer> siblings = getParent().mChildren;
+        final int zOrder = siblings.indexOf(this);
+
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            if (siblings.indexOf(getAdjacentTaskFragment()) < zOrder) {
+                // early return if this TF already has higher z-ordering.
+                return false;
+            }
+        } else {
+            final boolean hasAdjacentOnTop = forOtherAdjacentTaskFragments(
+                    tf -> siblings.indexOf(tf) > zOrder);
+            if (!hasAdjacentOnTop) {
+                // early return if this TF already has higher z-ordering.
+                return false;
+            }
         }
 
-        ToBooleanFunction<WindowState> getDimBehindWindow =
+        final ToBooleanFunction<WindowState> getDimBehindWindow =
                 (w) -> (w.mAttrs.flags & FLAG_DIM_BEHIND) != 0 && w.mActivityRecord != null
                         && w.mActivityRecord.isEmbedded() && (w.mActivityRecord.isVisibleRequested()
                         || w.mActivityRecord.isVisible());
-        if (adjacentTf.forAllWindows(getDimBehindWindow, true)) {
-            // early return if the adjacent Tf has a dimming window.
-            return false;
+
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            final TaskFragment adjacentTf = getAdjacentTaskFragment();
+            if (adjacentTf.forAllWindows(getDimBehindWindow, true)) {
+                // early return if the adjacent Tf has a dimming window.
+                return false;
+            }
+        } else {
+            final boolean adjacentHasDimmingWindow = forOtherAdjacentTaskFragments(tf -> {
+                return tf.forAllWindows(getDimBehindWindow, true);
+            });
+            if (adjacentHasDimmingWindow) {
+                // early return if the adjacent Tf has a dimming window.
+                return false;
+            }
         }
 
         // boost if there's an Activity window that has FLAG_DIM_BEHIND flag.
@@ -3267,9 +3384,16 @@
             sb.append(" organizerProc=");
             sb.append(mTaskFragmentOrganizerProcessName);
         }
-        if (mAdjacentTaskFragment != null) {
-            sb.append(" adjacent=");
-            sb.append(mAdjacentTaskFragment);
+        if (Flags.allowMultipleAdjacentTaskFragments()) {
+            if (mAdjacentTaskFragments != null) {
+                sb.append(" adjacent=");
+                sb.append(mAdjacentTaskFragments);
+            }
+        } else {
+            if (mAdjacentTaskFragment != null) {
+                sb.append(" adjacent=");
+                sb.append(mAdjacentTaskFragment);
+            }
         }
         sb.append('}');
         return sb.toString();
@@ -3385,4 +3509,125 @@
 
         proto.end(token);
     }
+
+    /** Set of {@link TaskFragment}s that are adjacent to each other. */
+    static class AdjacentSet {
+        private final ArraySet<TaskFragment> mAdjacentSet;
+
+        AdjacentSet(@NonNull TaskFragment... taskFragments) {
+            this(new ArraySet<>(taskFragments));
+        }
+
+        AdjacentSet(@NonNull ArraySet<TaskFragment> taskFragments) {
+            if (!Flags.allowMultipleAdjacentTaskFragments()) {
+                throw new IllegalStateException("allowMultipleAdjacentTaskFragments must be"
+                        + " enabled to set more than two TaskFragments adjacent to each other.");
+            }
+            if (taskFragments.size() < 2) {
+                throw new IllegalArgumentException("Adjacent TaskFragments must contain at least"
+                        + " two TaskFragments, but only " + taskFragments.size()
+                        + " were provided.");
+            }
+            mAdjacentSet = taskFragments;
+        }
+
+        /** Updates each {@link TaskFragment} in the set to be adjacent to each other. */
+        private void setAsAdjacent() {
+            if (mAdjacentSet.isEmpty()
+                    || equals(mAdjacentSet.valueAt(0).mAdjacentTaskFragments)) {
+                // No need to update if any TaskFragment in the set has already been updated to the
+                // same set.
+                return;
+            }
+            for (int i = mAdjacentSet.size() - 1; i >= 0; i--) {
+                final TaskFragment taskFragment = mAdjacentSet.valueAt(i);
+                taskFragment.removeFromAdjacentTaskFragments();
+                taskFragment.mAdjacentTaskFragments = this;
+            }
+        }
+
+        /** Removes the {@link TaskFragment} from the adjacent set. */
+        private void remove(@NonNull TaskFragment taskFragment) {
+            taskFragment.mAdjacentTaskFragments = null;
+            taskFragment.mDelayLastActivityRemoval = false;
+            mAdjacentSet.remove(taskFragment);
+            if (mAdjacentSet.size() < 2) {
+                // To be considered as adjacent, there must be at least 2 TaskFragments in the set.
+                clear();
+            }
+        }
+
+        /** Clears the adjacent relationship. */
+        private void clear() {
+            for (int i = mAdjacentSet.size() - 1; i >= 0; i--) {
+                final TaskFragment taskFragment = mAdjacentSet.valueAt(i);
+                // Clear all reference.
+                taskFragment.mAdjacentTaskFragments = null;
+                taskFragment.mDelayLastActivityRemoval = false;
+            }
+            mAdjacentSet.clear();
+        }
+
+        /** Whether the {@link TaskFragment} is in this adjacent set. */
+        boolean contains(@NonNull TaskFragment taskFragment) {
+            return mAdjacentSet.contains(taskFragment);
+        }
+
+        /**
+         * Runs the callback on all adjacent TaskFragments. Skips the exclude one if not null.
+         */
+        void forAllTaskFragments(@NonNull Consumer<TaskFragment> callback,
+                @Nullable TaskFragment exclude) {
+            for (int i = mAdjacentSet.size() - 1; i >= 0; i--) {
+                final TaskFragment taskFragment = mAdjacentSet.valueAt(i);
+                if (taskFragment != exclude) {
+                    callback.accept(taskFragment);
+                }
+            }
+        }
+
+        /**
+         * Runs the callback on all adjacent TaskFragments until one returns {@code true}. Skips the
+         * exclude one if not null.
+         */
+        boolean forAllTaskFragments(@NonNull Predicate<TaskFragment> callback,
+                @Nullable TaskFragment exclude) {
+            for (int i = mAdjacentSet.size() - 1; i >= 0; i--) {
+                final TaskFragment taskFragment = mAdjacentSet.valueAt(i);
+                if (taskFragment == exclude) {
+                    continue;
+                }
+                if (callback.test(taskFragment)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public boolean equals(@Nullable Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (!(o instanceof AdjacentSet other)) {
+                return false;
+            }
+            return mAdjacentSet.equals(other.mAdjacentSet);
+        }
+
+        @Override
+        public String toString() {
+            final StringBuilder sb = new StringBuilder();
+            sb.append("AdjacentSet{");
+            final int size = mAdjacentSet.size();
+            for (int i = 0; i < size; i++) {
+                if (i != 0) {
+                    sb.append(", ");
+                }
+                sb.append(mAdjacentSet.valueAt(i));
+            }
+            sb.append("}");
+            return sb.toString();
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotCache.java b/services/core/java/com/android/server/wm/TaskSnapshotCache.java
index 64b9df5..cc957bd 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotCache.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotCache.java
@@ -48,26 +48,37 @@
     }
 
     /**
-     * If {@param restoreFromDisk} equals {@code true}, DO NOT HOLD THE WINDOW MANAGER LOCK!
+     * Retrieves a snapshot from cache.
      */
-    @Nullable TaskSnapshot getSnapshot(int taskId, int userId, boolean restoreFromDisk,
-            boolean isLowResolution) {
-        final TaskSnapshot snapshot = getSnapshot(taskId);
-        if (snapshot != null) {
-            return snapshot;
-        }
+    @Nullable TaskSnapshot getSnapshot(int taskId, boolean isLowResolution) {
+        return getSnapshot(taskId, isLowResolution, TaskSnapshot.REFERENCE_NONE);
+    }
 
-        // Try to restore from disk if asked.
-        if (!restoreFromDisk) {
-            return null;
+    // TODO (b/238206323) Respect isLowResolution.
+    @Nullable TaskSnapshot getSnapshot(int taskId, boolean isLowResolution,
+            @TaskSnapshot.ReferenceFlags int usage) {
+        synchronized (mLock) {
+            final TaskSnapshot snapshot = getSnapshotInner(taskId);
+            if (snapshot != null) {
+                if (usage != TaskSnapshot.REFERENCE_NONE) {
+                    snapshot.addReference(usage);
+                }
+                return snapshot;
+            }
         }
-        return tryRestoreFromDisk(taskId, userId, isLowResolution);
+        return null;
     }
 
     /**
-     * DO NOT HOLD THE WINDOW MANAGER LOCK WHEN CALLING THIS METHOD!
+     * Restore snapshot from disk, DO NOT HOLD THE WINDOW MANAGER LOCK!
      */
-    private TaskSnapshot tryRestoreFromDisk(int taskId, int userId, boolean isLowResolution) {
-        return mLoader.loadTask(taskId, userId, isLowResolution);
+    @Nullable TaskSnapshot getSnapshotFromDisk(int taskId, int userId, boolean isLowResolution,
+            @TaskSnapshot.ReferenceFlags int usage) {
+        final TaskSnapshot snapshot = mLoader.loadTask(taskId, userId, isLowResolution);
+        // Note: This can be weird if the caller didn't ask for reference.
+        if (snapshot != null && usage != TaskSnapshot.REFERENCE_NONE) {
+            snapshot.addReference(usage);
+        }
+        return snapshot;
     }
 }
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index c130931..38a2ebe 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -174,14 +174,32 @@
     }
 
     /**
-     * Retrieves a snapshot. If {@param restoreFromDisk} equals {@code true}, DO NOT HOLD THE WINDOW
-     * MANAGER LOCK WHEN CALLING THIS METHOD!
+     * Retrieves a snapshot from cache.
      */
     @Nullable
-    TaskSnapshot getSnapshot(int taskId, int userId, boolean restoreFromDisk,
-            boolean isLowResolution) {
-        return mCache.getSnapshot(taskId, userId, restoreFromDisk, isLowResolution
-                && mPersistInfoProvider.enableLowResSnapshots());
+    TaskSnapshot getSnapshot(int taskId, boolean isLowResolution) {
+        return getSnapshot(taskId, false /* isLowResolution */, TaskSnapshot.REFERENCE_NONE);
+    }
+
+    /**
+     * Retrieves a snapshot from cache.
+     */
+    @Nullable
+    TaskSnapshot getSnapshot(int taskId, boolean isLowResolution,
+            @TaskSnapshot.ReferenceFlags int usage) {
+        return mCache.getSnapshot(taskId, isLowResolution
+                && mPersistInfoProvider.enableLowResSnapshots(), usage);
+    }
+
+    /**
+     * Retrieves a snapshot from disk.
+     * DO NOT HOLD THE WINDOW MANAGER LOCK WHEN CALLING THIS METHOD!
+     */
+    @Nullable
+    TaskSnapshot getSnapshotFromDisk(int taskId, int userId,
+            boolean isLowResolution, @TaskSnapshot.ReferenceFlags int usage) {
+        return mCache.getSnapshotFromDisk(taskId, userId, isLowResolution
+                && mPersistInfoProvider.enableLowResSnapshots(), usage);
     }
 
     /**
@@ -189,7 +207,7 @@
      * last taken, or -1 if no such snapshot exists for that task.
      */
     long getSnapshotCaptureTime(int taskId) {
-        final TaskSnapshot snapshot = mCache.getSnapshot(taskId);
+        final TaskSnapshot snapshot = mCache.getSnapshot(taskId, false /* isLowResolution */);
         if (snapshot != null) {
             return snapshot.getCaptureTime();
         }
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 1fc609b7..bcd12f2 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -1870,7 +1870,13 @@
             final DisplayArea<?> da = wc.asDisplayArea();
             if (da == null) continue;
             if (da.isVisibleRequested()) {
-                mController.mValidateDisplayVis.remove(da);
+                final int inValidateList = mController.mValidateDisplayVis.indexOf(da);
+                if (inValidateList >= 0
+                        // The display-area is visible, but if we only detect a non-visibility
+                        // change, then we shouldn't remove the validator.
+                        && !mChanges.get(da).mVisible) {
+                    mController.mValidateDisplayVis.remove(inValidateList);
+                }
             } else {
                 // In case something accidentally hides a displayarea and nothing shows it again.
                 mController.mValidateDisplayVis.add(da);
diff --git a/services/core/java/com/android/server/wm/WindowContextListenerController.java b/services/core/java/com/android/server/wm/WindowContextListenerController.java
index 809745e..6d0da1f 100644
--- a/services/core/java/com/android/server/wm/WindowContextListenerController.java
+++ b/services/core/java/com/android/server/wm/WindowContextListenerController.java
@@ -167,6 +167,22 @@
         return true;
     }
 
+    boolean assertCallerCanReparentListener(@NonNull IBinder clientToken,
+            boolean callerCanManageAppTokens, int callingUid, int displayId) {
+        if (!assertCallerCanModifyListener(clientToken, callerCanManageAppTokens, callingUid)) {
+            return false;
+        }
+
+        final WindowContainer<?> container = getContainer(clientToken);
+        if (container != null && container.getDisplayContent() != null
+                && container.getDisplayContent().mDisplayId == displayId) {
+            ProtoLog.i(WM_DEBUG_ADD_REMOVE,
+                    "The listener has already been attached to the same display id");
+            return false;
+        }
+        return true;
+    }
+
     boolean hasListener(IBinder clientToken) {
         return mListeners.containsKey(clientToken);
     }
diff --git a/services/core/java/com/android/server/wm/WindowManagerConstants.java b/services/core/java/com/android/server/wm/WindowManagerConstants.java
index 3ad9b62..9a5c8df 100644
--- a/services/core/java/com/android/server/wm/WindowManagerConstants.java
+++ b/services/core/java/com/android/server/wm/WindowManagerConstants.java
@@ -42,12 +42,23 @@
      * <ul>
      * <li>false: applies to no apps (default)</li>
      * <li>true: applies to all apps</li>
-     * <li>large: applies to all apps but only on large screens</li>
      * </ul>
      */
     private static final String KEY_IGNORE_ACTIVITY_ORIENTATION_REQUEST =
             "ignore_activity_orientation_request";
 
+    /**
+     * The orientation of activity will be always "unspecified" except for game apps.
+     * <p>Possible values:
+     * <ul>
+     * <li>none: applies to no apps (default)</li>
+     * <li>all: applies to all apps ({@see #KEY_IGNORE_ACTIVITY_ORIENTATION_REQUEST})</li>
+     * <li>large: applies to all apps but only on large screens</li>
+     * </ul>
+     */
+    private static final String KEY_IGNORE_ACTIVITY_ORIENTATION_REQUEST_SCREENS =
+            "ignore_activity_orientation_request_screens";
+
     /** The packages that ignore {@link #KEY_IGNORE_ACTIVITY_ORIENTATION_REQUEST}. */
     private static final String KEY_OPT_OUT_IGNORE_ACTIVITY_ORIENTATION_REQUEST_LIST =
             "opt_out_ignore_activity_orientation_request_list";
@@ -155,6 +166,7 @@
                         updateSystemGestureExclusionLogDebounceMillis();
                         break;
                     case KEY_IGNORE_ACTIVITY_ORIENTATION_REQUEST:
+                    case KEY_IGNORE_ACTIVITY_ORIENTATION_REQUEST_SCREENS:
                         updateIgnoreActivityOrientationRequest();
                         break;
                     case KEY_OPT_OUT_IGNORE_ACTIVITY_ORIENTATION_REQUEST_LIST:
@@ -186,12 +198,16 @@
     }
 
     private void updateIgnoreActivityOrientationRequest() {
-        final String value = mDeviceConfig.getProperty(
+        boolean allScreens = mDeviceConfig.getBoolean(
                 DeviceConfig.NAMESPACE_WINDOW_MANAGER,
-                KEY_IGNORE_ACTIVITY_ORIENTATION_REQUEST);
-        mIgnoreActivityOrientationRequestSmallScreen = Boolean.parseBoolean(value);
-        mIgnoreActivityOrientationRequestLargeScreen = mIgnoreActivityOrientationRequestSmallScreen
-                || ("large".equals(value));
+                KEY_IGNORE_ACTIVITY_ORIENTATION_REQUEST, false);
+        String whichScreens = mDeviceConfig.getProperty(
+                DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                KEY_IGNORE_ACTIVITY_ORIENTATION_REQUEST_SCREENS);
+        allScreens |= ("all".equalsIgnoreCase(whichScreens));
+        boolean largeScreens = allScreens || ("large".equalsIgnoreCase(whichScreens));
+        mIgnoreActivityOrientationRequestSmallScreen = allScreens;
+        mIgnoreActivityOrientationRequestLargeScreen = largeScreens;
     }
 
     private void updateOptOutIgnoreActivityOrientationRequestList() {
@@ -221,9 +237,9 @@
         pw.print("="); pw.println(mSystemGestureExclusionLimitDp);
         pw.print("  "); pw.print(KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE);
         pw.print("="); pw.println(mSystemGestureExcludedByPreQStickyImmersive);
-        pw.print("  "); pw.print(KEY_IGNORE_ACTIVITY_ORIENTATION_REQUEST);
-        pw.print("="); pw.println(mIgnoreActivityOrientationRequestSmallScreen ? "true"
-                : mIgnoreActivityOrientationRequestLargeScreen ? "large" : "false");
+        pw.print("  "); pw.print(KEY_IGNORE_ACTIVITY_ORIENTATION_REQUEST_SCREENS);
+        pw.print("="); pw.println(mIgnoreActivityOrientationRequestSmallScreen ? "all"
+                : mIgnoreActivityOrientationRequestLargeScreen ? "large" : "none");
         if (mOptOutIgnoreActivityOrientationRequestPackages != null) {
             pw.print("  "); pw.print(KEY_OPT_OUT_IGNORE_ACTIVITY_ORIENTATION_REQUEST_LIST);
             pw.print("="); pw.println(mOptOutIgnoreActivityOrientationRequestPackages);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b42ce64f..07e7a91 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -358,6 +358,7 @@
 import com.android.server.power.ShutdownThread;
 import com.android.server.utils.PriorityDump;
 import com.android.server.wallpaper.WallpaperCropper.WallpaperCropUtils;
+import com.android.window.flags.Flags;
 
 import dalvik.annotation.optimization.NeverCompile;
 
@@ -2672,7 +2673,7 @@
 
             if (outRelayoutResult != null) {
                 if (win.syncNextBuffer() && viewVisibility == View.VISIBLE
-                        && win.mSyncSeqId > lastSyncSeqId) {
+                        && win.mSyncSeqId > lastSyncSeqId && !displayContent.mWaitingForConfig) {
                     outRelayoutResult.syncSeqId = win.shouldSyncWithBuffers()
                             ? win.mSyncSeqId
                             : -1;
@@ -3042,6 +3043,81 @@
         }
     }
 
+    @Override
+    public boolean reparentWindowContextToDisplayArea(
+            @NonNull IApplicationThread appThread, @NonNull IBinder clientToken, int displayId) {
+        if (!Flags.reparentWindowTokenApi()) {
+            return false;
+        }
+        Objects.requireNonNull(appThread);
+        Objects.requireNonNull(clientToken);
+        final boolean callerCanManageAppTokens = checkCallingPermission(MANAGE_APP_TOKENS,
+                "reparentWindowContextToDisplayArea", false /* printLog */);
+        final int callingPid = Binder.getCallingPid();
+        final int callingUid = Binder.getCallingUid();
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final WindowProcessController wpc = mAtmService.getProcessController(appThread);
+                if (wpc == null) {
+                    ProtoLog.w(WM_ERROR, "reparentWindowContextToDisplayArea: calling from"
+                            + " non-existing process pid=%d uid=%d", callingPid, callingUid);
+                    return false;
+                }
+                final DisplayContent dc = mRoot.getDisplayContentOrCreate(displayId);
+                if (dc == null) {
+                    ProtoLog.w(WM_ERROR, "reparentWindowContextToDisplayArea: trying to attach"
+                            + " to a non-existing display:%d", displayId);
+                    return false;
+                }
+
+                if (!mWindowContextListenerController.assertCallerCanReparentListener(clientToken,
+                        callerCanManageAppTokens, callingUid, displayId)) {
+                    return false;
+                }
+                final WindowContainer<?> container = mWindowContextListenerController.getContainer(
+                                clientToken);
+
+                final WindowToken token = container != null ? container.asWindowToken() : null;
+                if (token != null && token.isFromClient()) {
+                    ProtoLog.d(WM_DEBUG_ADD_REMOVE, "Reparenting from dc to displayId=%d",
+                            displayId);
+                    // Reparent the window created for this window context.
+                    dc.reParentWindowToken(token);
+                    hideUntilNextDraw(token);
+                    // This makes sure there is a traversal scheduled that will eventually report
+                    // the window resize to the client.
+                    dc.setLayoutNeeded();
+                    requestTraversal();
+                    return true;
+                }
+
+                final int type = mWindowContextListenerController.getWindowType(clientToken);
+                final Bundle options = mWindowContextListenerController.getOptions(clientToken);
+                // No window yet, switch listening DA.
+                final DisplayArea<?> da = dc.findAreaForWindowType(type, options,
+                        callerCanManageAppTokens, false /* roundedCornerOverlay */);
+                mWindowContextListenerController.registerWindowContainerListener(wpc, clientToken,
+                        da, type, options, true /* shouldDispatchConfigWhenRegistering */);
+                return true;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    private void hideUntilNextDraw(@NonNull WindowToken token) {
+        final WindowState topChild = token.getTopChild();
+        if (topChild != null) {
+            mTransactionFactory.get().hide(token.mSurfaceControl).apply();
+            topChild.applyWithNextDraw(t -> {
+                if (token.mSurfaceControl != null) {
+                    t.show(token.mSurfaceControl);
+                }
+            });
+        }
+    }
+
     /** Returns {@code true} if this binder is a registered window token. */
     @Override
     public boolean isWindowToken(IBinder binder) {
@@ -4216,16 +4292,6 @@
     }
 
     /**
-     * Retrieves a snapshot. If restoreFromDisk equals equals {@code true}, DO NOT HOLD THE WINDOW
-     * MANAGER LOCK WHEN CALLING THIS METHOD!
-     */
-    public TaskSnapshot getTaskSnapshot(int taskId, int userId, boolean isLowResolution,
-            boolean restoreFromDisk) {
-        return mTaskSnapshotController.getSnapshot(taskId, userId, restoreFromDisk,
-                isLowResolution);
-    }
-
-    /**
      * Generates and returns an up-to-date {@link Bitmap} for the specified taskId.
      *
      * @param taskId                  The task ID of the task for which a Bitmap is requested.
@@ -9020,16 +9086,19 @@
 
         clearPointerDownOutsideFocusRunnable();
 
+        final InputTarget focusedInputTarget = mFocusedInputTarget;
         if (shouldDelayTouchOutside(t)) {
-            mPointerDownOutsideFocusRunnable = () -> handlePointerDownOutsideFocus(t);
+            mPointerDownOutsideFocusRunnable =
+                    () -> handlePointerDownOutsideFocus(t, focusedInputTarget);
             mH.postDelayed(mPointerDownOutsideFocusRunnable, POINTER_DOWN_OUTSIDE_FOCUS_TIMEOUT_MS);
         } else if (!fromHandler) {
             // Still post the runnable to handler thread in case there is already a runnable
             // in execution, but still waiting to hold the wm lock.
-            mPointerDownOutsideFocusRunnable = () -> handlePointerDownOutsideFocus(t);
+            mPointerDownOutsideFocusRunnable =
+                    () -> handlePointerDownOutsideFocus(t, focusedInputTarget);
             mH.post(mPointerDownOutsideFocusRunnable);
         } else {
-            handlePointerDownOutsideFocus(t);
+            handlePointerDownOutsideFocus(t, focusedInputTarget);
         }
     }
 
@@ -9061,8 +9130,15 @@
         return shouldDelayTouchForEmbeddedActivity || shouldDelayTouchForFreeform;
     }
 
-    private void handlePointerDownOutsideFocus(InputTarget t) {
+    private void handlePointerDownOutsideFocus(InputTarget t, InputTarget focusedInputTarget) {
         synchronized (mGlobalLock) {
+            if (mFocusedInputTarget != focusedInputTarget) {
+                // Skip if the mFocusedInputTarget is already changed. This is possible if the
+                // pointer-down-outside-focus event is delayed to be handled.
+                ProtoLog.i(WM_DEBUG_FOCUS_LIGHT,
+                        "Skip onPointerDownOutsideFocusLocked due to input target changed %s", t);
+                return;
+            }
             if (mPointerDownOutsideFocusRunnable != null
                     && mH.hasCallbacks(mPointerDownOutsideFocusRunnable)) {
                 // Skip if there's another pending pointer-down-outside-focus event.
@@ -9935,11 +10011,10 @@
                     && imeTargetWindow.mActivityRecord.mLastImeShown) {
                 return true;
             }
+            final TaskSnapshot snapshot = mTaskSnapshotController.getSnapshot(
+                    imeTargetWindowTask.mTaskId, false /* isLowResolution */);
+            return snapshot != null && snapshot.hasImeSurface();
         }
-        final TaskSnapshot snapshot = getTaskSnapshot(imeTargetWindowTask.mTaskId,
-                imeTargetWindowTask.mUserId, false /* isLowResolution */,
-                false /* restoreFromDisk */);
-        return snapshot != null && snapshot.hasImeSurface();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 66921ff..fb197c5 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -1155,7 +1155,7 @@
                 } else if (!task.mCreatedByOrganizer) {
                     throw new UnsupportedOperationException(
                             "Cannot set non-organized task as adjacent flag root: " + wc);
-                } else if (task.getAdjacentTaskFragment() == null && !clearRoot) {
+                } else if (!task.hasAdjacentTaskFragment() && !clearRoot) {
                     throw new UnsupportedOperationException(
                             "Cannot set non-adjacent task as adjacent flag root: " + wc);
                 }
@@ -1645,9 +1645,15 @@
                             opType, exception);
                     break;
                 }
-                if (taskFragment.getAdjacentTaskFragment() != secondaryTaskFragment) {
+                if (!taskFragment.isAdjacentTo(secondaryTaskFragment)) {
                     // Only have lifecycle effect if the adjacent changed.
-                    taskFragment.setAdjacentTaskFragment(secondaryTaskFragment);
+                    if (Flags.allowMultipleAdjacentTaskFragments()) {
+                        // Activity Embedding only set two TFs adjacent.
+                        taskFragment.setAdjacentTaskFragments(
+                                new TaskFragment.AdjacentSet(taskFragment, secondaryTaskFragment));
+                    } else {
+                        taskFragment.setAdjacentTaskFragment(secondaryTaskFragment);
+                    }
                     effects |= TRANSACT_EFFECTS_LIFECYCLE;
                 }
 
@@ -1663,21 +1669,25 @@
                 break;
             }
             case OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS: {
-                final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment();
-                if (adjacentTaskFragment == null) {
+                if (!taskFragment.hasAdjacentTaskFragment()) {
                     break;
                 }
-                taskFragment.resetAdjacentTaskFragment();
-                effects |= TRANSACT_EFFECTS_LIFECYCLE;
 
-                // Clear the focused app if the focused app is no longer visible after reset the
-                // adjacent TaskFragments.
+                // Check if the focused app is in the adjacent set that will be cleared.
                 final ActivityRecord focusedApp = taskFragment.getDisplayContent().mFocusedApp;
                 final TaskFragment focusedTaskFragment = focusedApp != null
                         ? focusedApp.getTaskFragment()
                         : null;
-                if ((focusedTaskFragment == taskFragment
-                        || focusedTaskFragment == adjacentTaskFragment)
+                final boolean wasFocusedInAdjacent = focusedTaskFragment == taskFragment
+                        || (focusedTaskFragment != null
+                        && taskFragment.isAdjacentTo(focusedTaskFragment));
+
+                taskFragment.removeFromAdjacentTaskFragments();
+                effects |= TRANSACT_EFFECTS_LIFECYCLE;
+
+                // Clear the focused app if the focused app is no longer visible after reset the
+                // adjacent TaskFragments.
+                if (wasFocusedInAdjacent
                         && !focusedTaskFragment.shouldBeVisible(null /* starting */)) {
                     focusedTaskFragment.getDisplayContent().setFocusedApp(null /* newFocus */);
                 }
@@ -2191,26 +2201,60 @@
     }
 
     private int setAdjacentRootsHierarchyOp(WindowContainerTransaction.HierarchyOp hop) {
-        final WindowContainer wc1 = WindowContainer.fromBinder(hop.getContainer());
-        if (wc1 == null || !wc1.isAttached()) {
-            Slog.e(TAG, "Attempt to operate on unknown or detached container: " + wc1);
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            final WindowContainer wc1 = WindowContainer.fromBinder(hop.getContainer());
+            if (wc1 == null || !wc1.isAttached()) {
+                Slog.e(TAG, "Attempt to operate on unknown or detached container: " + wc1);
+                return TRANSACT_EFFECTS_NONE;
+            }
+            final TaskFragment root1 = wc1.asTaskFragment();
+            final WindowContainer wc2 = WindowContainer.fromBinder(hop.getAdjacentRoot());
+            if (wc2 == null || !wc2.isAttached()) {
+                Slog.e(TAG, "Attempt to operate on unknown or detached container: " + wc2);
+                return TRANSACT_EFFECTS_NONE;
+            }
+            final TaskFragment root2 = wc2.asTaskFragment();
+            if (!root1.mCreatedByOrganizer || !root2.mCreatedByOrganizer) {
+                throw new IllegalArgumentException("setAdjacentRootsHierarchyOp: Not created by"
+                        + " organizer root1=" + root1 + " root2=" + root2);
+            }
+            if (root1.isAdjacentTo(root2)) {
+                return TRANSACT_EFFECTS_NONE;
+            }
+            root1.setAdjacentTaskFragment(root2);
+            return TRANSACT_EFFECTS_LIFECYCLE;
+        }
+
+        final IBinder[] containers = hop.getContainers();
+        final ArraySet<TaskFragment> adjacentRoots = new ArraySet<>();
+        for (IBinder container : containers) {
+            final WindowContainer wc = WindowContainer.fromBinder(container);
+            if (wc == null || !wc.isAttached()) {
+                Slog.e(TAG, "Attempt to operate on unknown or detached container: " + wc);
+                return TRANSACT_EFFECTS_NONE;
+            }
+            final Task root = wc.asTask();
+            if (root == null) {
+                // Only support Task. Use WCT#setAdjacentTaskFragments for non-Task TaskFragment.
+                throw new IllegalArgumentException("setAdjacentRootsHierarchyOp: Not called with"
+                        + " Task. wc=" + wc);
+            }
+            if (!root.mCreatedByOrganizer) {
+                throw new IllegalArgumentException("setAdjacentRootsHierarchyOp: Not created by"
+                        + " organizer root=" + root);
+            }
+            if (adjacentRoots.contains(root)) {
+                throw new IllegalArgumentException("setAdjacentRootsHierarchyOp: called with same"
+                        + " root twice=" + root);
+            }
+            adjacentRoots.add(root);
+        }
+        final TaskFragment root0 = adjacentRoots.valueAt(0);
+        final TaskFragment.AdjacentSet adjacentSet = new TaskFragment.AdjacentSet(adjacentRoots);
+        if (adjacentSet.equals(root0.getAdjacentTaskFragments())) {
             return TRANSACT_EFFECTS_NONE;
         }
-        final TaskFragment root1 = wc1.asTaskFragment();
-        final WindowContainer wc2 = WindowContainer.fromBinder(hop.getAdjacentRoot());
-        if (wc2 == null || !wc2.isAttached()) {
-            Slog.e(TAG, "Attempt to operate on unknown or detached container: " + wc2);
-            return TRANSACT_EFFECTS_NONE;
-        }
-        final TaskFragment root2 = wc2.asTaskFragment();
-        if (!root1.mCreatedByOrganizer || !root2.mCreatedByOrganizer) {
-            throw new IllegalArgumentException("setAdjacentRootsHierarchyOp: Not created by"
-                    + " organizer root1=" + root1 + " root2=" + root2);
-        }
-        if (root1.getAdjacentTaskFragment() == root2) {
-            return TRANSACT_EFFECTS_NONE;
-        }
-        root1.setAdjacentTaskFragment(root2);
+        root0.setAdjacentTaskFragments(adjacentSet);
         return TRANSACT_EFFECTS_LIFECYCLE;
     }
 
@@ -2225,10 +2269,10 @@
             throw new IllegalArgumentException("clearAdjacentRootsHierarchyOp: Not created by"
                     + " organizer root=" + root);
         }
-        if (root.getAdjacentTaskFragment() == null) {
+        if (!root.hasAdjacentTaskFragment()) {
             return TRANSACT_EFFECTS_NONE;
         }
-        root.resetAdjacentTaskFragment();
+        root.removeFromAdjacentTaskFragments();
         return TRANSACT_EFFECTS_LIFECYCLE;
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 7f0c336..80e4c30 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -1263,7 +1263,7 @@
                     if (windowingMode == WINDOWING_MODE_MULTI_WINDOW
                             && com.android.window.flags.Flags
                                     .processPriorityPolicyForMultiWindowMode()
-                            && task.getAdjacentTask() != null) {
+                            && task.hasAdjacentTask()) {
                         stateFlags |= ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN;
                     } else if (windowingMode == WINDOWING_MODE_FREEFORM) {
                         hasResumedFreeform = true;
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 832295a..cca73c57 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -49,6 +49,7 @@
 
 import com.android.internal.protolog.ProtoLog;
 import com.android.server.policy.WindowManagerPolicy;
+import com.android.window.flags.Flags;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -386,7 +387,15 @@
 
     @Override
     void onDisplayChanged(DisplayContent dc) {
-        dc.reParentWindowToken(this);
+        if (!Flags.reparentWindowTokenApi()) {
+            dc.reParentWindowToken(this);
+        } else {
+            // This check is needed to break recursion, as DisplayContent#reparentWindowToken also
+            // triggers a WindowToken#onDisplayChanged.
+            if (dc.getWindowToken(token) == null) {
+                dc.reParentWindowToken(this);
+            }
+        }
 
         // TODO(b/36740756): One day this should perhaps be hooked
         // up with goodToGo, so we don't move a window
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 4c0cee4..82699ea 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -11,7 +11,6 @@
     name: "libservices.core",
     defaults: ["libservices.core-libs"],
 
-    cpp_std: "c++2a",
     cflags: [
         "-Wall",
         "-Werror",
diff --git a/services/core/jni/com_android_server_am_Freezer.cpp b/services/core/jni/com_android_server_am_Freezer.cpp
index 8148728..e9a99f0 100644
--- a/services/core/jni/com_android_server_am_Freezer.cpp
+++ b/services/core/jni/com_android_server_am_Freezer.cpp
@@ -68,7 +68,7 @@
 
 bool isFreezerSupported(JNIEnv *env, jclass) {
     std::string path;
-    if (!getAttributePathForTask("FreezerState", getpid(), &path)) {
+    if (!CgroupGetAttributePathForTask("FreezerState", getpid(), &path)) {
         ALOGI("No attribute for FreezerState");
         return false;
     }
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
index 0c9a89b..8533eaf 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
@@ -114,7 +114,7 @@
     /** Creates intent that is ot be invoked to cancel an in-progress UI session. */
     public Intent createCancelIntent(IBinder requestId, String packageName) {
         return IntentFactory.createCancelUiIntent(mContext, requestId,
-                /*shouldShowCancellationUi=*/ true, packageName);
+                /*shouldShowCancellationUi=*/ true, packageName, mUserId);
     }
 
     /**
@@ -177,7 +177,7 @@
 
         IntentCreationResult intentCreationResult = IntentFactory
                 .createCredentialSelectorIntentForCredMan(mContext, requestInfo, providerDataList,
-                        new ArrayList<>(disabledProviderDataList), mResultReceiver);
+                        new ArrayList<>(disabledProviderDataList), mResultReceiver, mUserId);
         requestSessionMetric.collectUiConfigurationResults(
                 mContext, intentCreationResult, mUserId);
         Intent intent = intentCreationResult.getIntent();
@@ -211,7 +211,7 @@
             RequestSessionMetric requestSessionMetric) {
         IntentCreationResult intentCreationResult = IntentFactory
                 .createCredentialSelectorIntentForAutofill(mContext, requestInfo, new ArrayList<>(),
-                        mResultReceiver);
+                        mResultReceiver, mUserId);
         requestSessionMetric.collectUiConfigurationResults(
                 mContext, intentCreationResult, mUserId);
         return intentCreationResult.getIntent();
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 65315af..29e0487 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -293,6 +293,7 @@
 import com.android.server.usage.UsageStatsService;
 import com.android.server.usb.UsbService;
 import com.android.server.utils.TimingsTraceAndSlog;
+import com.android.server.vcn.VcnLocation;
 import com.android.server.vibrator.VibratorManagerService;
 import com.android.server.voiceinteraction.VoiceInteractionManagerService;
 import com.android.server.vr.VrManagerService;
@@ -1929,6 +1930,10 @@
         }
         t.traceEnd();
 
+        t.traceBegin("UpdateMetricsIfNeeded");
+        mPackageManagerService.updateMetricsIfNeeded();
+        t.traceEnd();
+
         t.traceBegin("PerformFstrimIfNeeded");
         try {
             mPackageManagerService.performFstrimIfNeeded();
@@ -2234,10 +2239,13 @@
 
             t.traceBegin("StartVcnManagementService");
             try {
-                // TODO: b/375213246 When VCN is in mainline module, load it from the apex path.
-                // Whether VCN will be in apex or in the platform will be gated by a build system
-                // flag.
-                mSystemServiceManager.startService(CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS);
+                if (VcnLocation.IS_VCN_IN_MAINLINE) {
+                    mSystemServiceManager.startServiceFromJar(
+                            CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS,
+                            CONNECTIVITY_SERVICE_APEX_PATH);
+                } else {
+                    mSystemServiceManager.startService(CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS);
+                }
             } catch (Throwable e) {
                 reportWtf("starting VCN Management Service", e);
             }
@@ -2933,7 +2941,7 @@
         t.traceEnd();
 
         // UprobeStats DynamicInstrumentationManager
-        if (com.android.art.flags.Flags.executableMethodFileOffsets()) {
+        if (android.uprobestats.flags.Flags.executableMethodFileOffsets()) {
             t.traceBegin("StartDynamicInstrumentationManager");
             mSystemServiceManager.startService(DynamicInstrumentationManagerService.class);
             t.traceEnd();
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/BroadcastHelperTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/BroadcastHelperTest.java
index acd34e3..0ae7699 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/BroadcastHelperTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/BroadcastHelperTest.java
@@ -233,6 +233,6 @@
 
         mBroadcastHelper.sendPackageChangedBroadcast(mMockSnapshot,
                 PACKAGE_CHANGED_TEST_PACKAGE_NAME, true /* dontKillApp */, componentNames,
-                UserHandle.USER_SYSTEM, "test" /* reason */);
+                UserHandle.USER_SYSTEM, "test" /* reason */, "test" /* reasonForTrace */);
     }
 }
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
index 365cbae..724f083 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -3708,7 +3708,7 @@
                 eq(config));
 
         bs.releaseVirtualDisplay(mMockAppToken);
-        verify(mMockVirtualDisplayAdapter).releaseVirtualDisplayLocked(binder, callingUid);
+        verify(mMockVirtualDisplayAdapter).releaseVirtualDisplayLocked(binder);
     }
 
     @Test
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 91f1aaf..8ca3919 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -2471,6 +2471,26 @@
                 eq(false));
     }
 
+    @Test
+    public void onDisplayChange_canceledAfterStop() {
+        mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
+
+        // stop the dpc (turn it down)
+        mHolder.dpc.stop();
+        advanceTime(1);
+
+        // To trigger all the changes that can happen, we will completely change the underlying
+        // display device.
+        setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
+                mock(DisplayDeviceConfig.class), /* isEnabled= */ true);
+
+        // Call onDisplayChange after we stopped DPC and make sure it doesn't crash
+        mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY);
+        advanceTime(1);
+
+        // No crash = success
+    }
+
     /**
      * Creates a mock and registers it to {@link LocalServices}.
      */
diff --git a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
index dbd5c65..9287b30 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
@@ -118,14 +118,13 @@
     public void testCreateAndReleaseVirtualDisplay() {
         VirtualDisplayConfig config = new VirtualDisplayConfig.Builder("test", /* width= */ 1,
                 /* height= */ 1, /* densityDpi= */ 1).build();
-        int ownerUid = 10;
 
         DisplayDevice result = mAdapter.createVirtualDisplayLocked(mMockCallback,
-                /* projection= */ null, ownerUid, /* packageName= */ "testpackage",
+                /* projection= */ null, /* ownerUid= */ 10, /* packageName= */ "testpackage",
                 /* uniqueId= */ "uniqueId", /* surface= */ null, /* flags= */ 0, config);
         assertNotNull(result);
 
-        result = mAdapter.releaseVirtualDisplayLocked(mMockBinder, ownerUid);
+        result = mAdapter.releaseVirtualDisplayLocked(mMockBinder);
         assertNotNull(result);
     }
 
@@ -230,7 +229,6 @@
 
         // Displays for the same package
         for (int i = 0; i < MAX_DEVICES_PER_PACKAGE * 2; i++) {
-            // Same owner UID
             IVirtualDisplayCallback callback = createCallback();
             DisplayDevice device = mAdapter.createVirtualDisplayLocked(callback,
                     mMediaProjectionMock, 1234, "test.package", "123",
@@ -240,7 +238,6 @@
 
         // Displays for different packages
         for (int i = 0; i < MAX_DEVICES * 2; i++) {
-            // Same owner UID
             IVirtualDisplayCallback callback = createCallback();
             DisplayDevice device = mAdapter.createVirtualDisplayLocked(callback,
                     mMediaProjectionMock, 1234 + i, "test.package", "123",
@@ -270,8 +267,7 @@
         }
 
         // Release one display
-        DisplayDevice device = mAdapter.releaseVirtualDisplayLocked(callbacks.get(0).asBinder(),
-                ownerUid);
+        DisplayDevice device = mAdapter.releaseVirtualDisplayLocked(callbacks.get(0).asBinder());
         assertNotNull(device);
         callbacks.remove(0);
 
@@ -292,7 +288,7 @@
 
         // Release all the displays
         for (IVirtualDisplayCallback cb : callbacks) {
-            device = mAdapter.releaseVirtualDisplayLocked(cb.asBinder(), ownerUid);
+            device = mAdapter.releaseVirtualDisplayLocked(cb.asBinder());
             assertNotNull(device);
         }
         callbacks.clear();
@@ -342,8 +338,7 @@
         }
 
         // Release one display
-        DisplayDevice device = mAdapter.releaseVirtualDisplayLocked(callbacks.get(0).asBinder(),
-                firstOwnerUid);
+        DisplayDevice device = mAdapter.releaseVirtualDisplayLocked(callbacks.get(0).asBinder());
         assertNotNull(device);
         callbacks.remove(0);
 
@@ -363,9 +358,8 @@
         assertNull(device);
 
         // Release all the displays
-        for (int i = 0; i < callbacks.size(); i++) {
-            device = mAdapter.releaseVirtualDisplayLocked(callbacks.get(i).asBinder(),
-                    firstOwnerUid + i);
+        for (IVirtualDisplayCallback iVirtualDisplayCallback : callbacks) {
+            device = mAdapter.releaseVirtualDisplayLocked(iVirtualDisplayCallback.asBinder());
             assertNotNull(device);
         }
         callbacks.clear();
diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/RejectedModesVoteTest.kt b/services/tests/displayservicetests/src/com/android/server/display/mode/RejectedModesVoteTest.kt
new file mode 100644
index 0000000..dd3211d
--- /dev/null
+++ b/services/tests/displayservicetests/src/com/android/server/display/mode/RejectedModesVoteTest.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.server.display.mode
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class RejectedModesVoteTest {
+    private val rejectedModes = setOf(1, 2)
+
+    private val otherMode = 2
+
+    private lateinit var rejectedModesVote: RejectedModesVote
+
+    @Before
+    fun setUp() {
+        rejectedModesVote = RejectedModesVote(rejectedModes)
+    }
+
+    @Test
+    fun addsRejectedModeIds_summaryIsEmpty() {
+        val summary = createVotesSummary()
+
+        rejectedModesVote.updateSummary(summary)
+
+        assertThat(summary.rejectedModeIds).containsExactlyElementsIn(rejectedModes)
+    }
+
+    @Test
+    fun addsRejectedModeIds_summaryIsNotEmpty() {
+        val summary = createVotesSummary()
+        summary.rejectedModeIds.add(otherMode)
+
+        rejectedModesVote.updateSummary(summary)
+
+        assertThat(summary.rejectedModeIds).containsExactlyElementsIn(rejectedModes + otherMode)
+    }
+}
\ No newline at end of file
diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/VoteSummaryTest.kt b/services/tests/displayservicetests/src/com/android/server/display/mode/VoteSummaryTest.kt
index 239e59b..958cf21 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/mode/VoteSummaryTest.kt
+++ b/services/tests/displayservicetests/src/com/android/server/display/mode/VoteSummaryTest.kt
@@ -186,6 +186,44 @@
 
         assertThat(result).hasSize(1)
     }
+
+    enum class RejectedModesTestCase(
+            internal val summaryRejectedModes: Set<Int>?,
+            val modesToFilter: Array<Display.Mode>,
+            val expectedModeIds: Set<Int>
+    ) {
+        HAS_NO_MATCHING_VOTE(
+                setOf(4, 5),
+                arrayOf(createMode(1, 90f, 90f),
+                        createMode(2, 90f, 60f),
+                        createMode(3, 60f, 90f)),
+                setOf(1, 2, 3)
+        ),
+        HAS_SINGLE_MATCHING_VOTE(
+                setOf(1),
+                arrayOf(createMode(1, 90f, 90f),
+                        createMode(2, 90f, 60f),
+                        createMode(3, 60f, 90f)),
+                setOf(2, 3)
+        ),
+        HAS_MULTIPLE_MATCHING_VOTES(
+                setOf(1, 2),
+                arrayOf(createMode(1, 90f, 90f),
+                        createMode(2, 90f, 60f),
+                        createMode(3, 60f, 90f)),
+                setOf(3)
+        ),
+    }
+
+    @Test
+    fun testFilterModes_rejectedModes(@TestParameter testCase: RejectedModesTestCase) {
+        val summary = createSummary()
+        summary.rejectedModeIds = testCase.summaryRejectedModes
+
+        val result = summary.filterModes(testCase.modesToFilter)
+
+        assertThat(result.map {it.modeId}).containsExactlyElementsIn(testCase.expectedModeIds)
+    }
 }
 
 
diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamControllerTest.java b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamControllerTest.java
index 874e991..495e853 100644
--- a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamControllerTest.java
+++ b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamControllerTest.java
@@ -46,7 +46,6 @@
 import android.os.test.TestLooper;
 import android.service.dreams.IDreamService;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -108,10 +107,8 @@
                 .thenReturn(Context.ACTIVITY_TASK_SERVICE);
 
         final PowerManager powerManager = new PowerManager(mContext, mPowerManager, null, null);
-        when(mContext.getSystemService(Context.POWER_SERVICE))
+        when(mContext.getSystemService(PowerManager.class))
                 .thenReturn(powerManager);
-        when(mContext.getSystemServiceName(PowerManager.class))
-                .thenReturn(Context.POWER_SERVICE);
         when(mContext.getResources()).thenReturn(mResources);
 
         mToken = new Binder();
@@ -234,8 +231,13 @@
     }
 
     @Test
-    @FlakyTest(bugId = 293109503)
     public void serviceDisconnect_resetsScreenTimeout() throws RemoteException {
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_resetScreenTimeoutOnUnexpectedDreamExit))
+                .thenReturn(true);
+        // Recreate DreamManager because the configuration gets retrieved in the constructor
+        mDreamController = new DreamController(mContext, mHandler, mListener);
+
         // Start dream.
         mDreamController.startDream(mToken, mDreamName, false /*isPreview*/, false /*doze*/,
                 0 /*userId*/, null /*wakeLock*/, mOverlayName, "test" /*reason*/);
@@ -254,8 +256,13 @@
     }
 
     @Test
-    @FlakyTest(bugId = 293109503)
     public void binderDied_resetsScreenTimeout() throws RemoteException {
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_resetScreenTimeoutOnUnexpectedDreamExit))
+                .thenReturn(true);
+        // Recreate DreamManager because the configuration gets retrieved in the constructor
+        mDreamController = new DreamController(mContext, mHandler, mListener);
+
         // Start dream.
         mDreamController.startDream(mToken, mDreamName, false /*isPreview*/, false /*doze*/,
                 0 /*userId*/, null /*wakeLock*/, mOverlayName, "test" /*reason*/);
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt
index de029e0..90e1263 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt
@@ -56,8 +56,8 @@
         testHandler.flush()
 
         verify(pms).scheduleWritePackageRestrictions(eq(TEST_USER_ID))
-        verify(broadcastHelper).sendDistractingPackagesChanged(any(Computer::class.java),
-                pkgListCaptor.capture(), any(), any(), flagsCaptor.capture())
+        verify(broadcastHelper).sendDistractingPackagesChanged(
+            any(), pkgListCaptor.capture(), any(), any(), flagsCaptor.capture())
 
         val modifiedPackages = pkgListCaptor.value
         val distractionFlags = flagsCaptor.value
@@ -158,8 +158,7 @@
 
         verify(pms).scheduleWritePackageRestrictions(eq(TEST_USER_ID))
         verify(broadcastHelper).sendDistractingPackagesChanged(
-                any(Computer::class.java), pkgListCaptor.capture(), any(), eq(TEST_USER_ID),
-                flagsCaptor.capture())
+                any(), pkgListCaptor.capture(), any(), eq(TEST_USER_ID), flagsCaptor.capture())
         val modifiedPackages = pkgListCaptor.value
         val distractionFlags = flagsCaptor.value
         assertThat(modifiedPackages).asList().containsExactly(TEST_PACKAGE_1, TEST_PACKAGE_2)
@@ -198,12 +197,12 @@
 
     @Test
     fun sendDistractingPackagesChanged() {
-        broadcastHelper.sendDistractingPackagesChanged(pms.snapshotComputer(),
+        broadcastHelper.sendDistractingPackagesChanged(pms::snapshotComputer,
                 packagesToChange, uidsToChange, TEST_USER_ID,
                 PackageManager.RESTRICTION_HIDE_NOTIFICATIONS)
         testHandler.flush()
-        verify(broadcastHelper).sendDistractingPackagesChanged(any(Computer::class.java),
-                pkgListCaptor.capture(), uidsCaptor.capture(), eq(TEST_USER_ID), any())
+        verify(broadcastHelper).sendDistractingPackagesChanged(
+                any(), pkgListCaptor.capture(), uidsCaptor.capture(), eq(TEST_USER_ID), any())
 
         var changedPackages = pkgListCaptor.value
         var changedUids = uidsCaptor.value
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/InstallDependencyHelperTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/InstallDependencyHelperTest.java
index 0304a74..cd8d415 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/InstallDependencyHelperTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/InstallDependencyHelperTest.java
@@ -21,11 +21,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.pm.SharedLibraryInfo;
@@ -90,32 +86,15 @@
     }
 
     @Test
-    public void testResolveLibraryDependenciesIfNeeded_errorInSharedLibrariesImpl()
-            throws Exception {
-        doThrow(new PackageManagerException(new Exception("xyz")))
-                .when(mSharedLibraries).collectMissingSharedLibraryInfos(any());
-
-        PackageLite pkg = getPackageLite(TEST_APP_USING_SDK1_AND_SDK2);
-        CallbackHelper callback = new CallbackHelper(/*expectSuccess=*/ false);
-        mInstallDependencyHelper.resolveLibraryDependenciesIfNeeded(pkg, mComputer,
-                0, mHandler, callback);
-        callback.assertFailure();
-
-        assertThat(callback.error).hasMessageThat().contains("xyz");
-    }
-
-    @Test
     public void testResolveLibraryDependenciesIfNeeded_failsToBind() throws Exception {
         // Return a non-empty list as missing dependency
         PackageLite pkg = getPackageLite(TEST_APP_USING_SDK1_AND_SDK2);
         List<SharedLibraryInfo> missingDependency = Collections.singletonList(
                 mock(SharedLibraryInfo.class));
-        when(mSharedLibraries.collectMissingSharedLibraryInfos(eq(pkg)))
-                .thenReturn(missingDependency);
 
         CallbackHelper callback = new CallbackHelper(/*expectSuccess=*/ false);
-        mInstallDependencyHelper.resolveLibraryDependenciesIfNeeded(pkg, mComputer,
-                0, mHandler, callback);
+        mInstallDependencyHelper.resolveLibraryDependenciesIfNeeded(missingDependency, pkg,
+                mComputer, 0, mHandler, callback);
         callback.assertFailure();
 
         assertThat(callback.error).hasMessageThat().contains(
@@ -128,12 +107,10 @@
         // Return an empty list as missing dependency
         PackageLite pkg = getPackageLite(TEST_APP_USING_SDK1_AND_SDK2);
         List<SharedLibraryInfo> missingDependency = Collections.emptyList();
-        when(mSharedLibraries.collectMissingSharedLibraryInfos(eq(pkg)))
-                .thenReturn(missingDependency);
 
         CallbackHelper callback = new CallbackHelper(/*expectSuccess=*/ true);
-        mInstallDependencyHelper.resolveLibraryDependenciesIfNeeded(pkg, mComputer,
-                0, mHandler, callback);
+        mInstallDependencyHelper.resolveLibraryDependenciesIfNeeded(missingDependency, pkg,
+                mComputer, 0, mHandler, callback);
         callback.assertSuccess();
     }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt
index 7444403..60e8250 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt
@@ -58,8 +58,8 @@
         testHandler.flush()
 
         verify(pms).scheduleWritePackageRestrictions(eq(TEST_USER_ID))
-        verify(broadcastHelper).sendPackagesSuspendedOrUnsuspendedForUser(any(Computer::class.java),
-            eq(Intent.ACTION_PACKAGES_SUSPENDED), pkgListCaptor.capture(), any(), any(), any())
+        verify(broadcastHelper).sendPackagesSuspendedOrUnsuspendedForUser(any(),
+                eq(Intent.ACTION_PACKAGES_SUSPENDED), pkgListCaptor.capture(), any(), any(), any())
 
         var modifiedPackages = pkgListCaptor.value
         assertThat(modifiedPackages).asList().containsExactly(TEST_PACKAGE_1, TEST_PACKAGE_2)
@@ -149,11 +149,11 @@
         testHandler.flush()
 
         verify(pms, times(2)).scheduleWritePackageRestrictions(eq(TEST_USER_ID))
-        verify(broadcastHelper).sendPackagesSuspendedOrUnsuspendedForUser(any(Computer::class.java),
-                eq(Intent.ACTION_PACKAGES_UNSUSPENDED), pkgListCaptor.capture(), any(), any(),
-                any())
-        verify(broadcastHelper).sendMyPackageSuspendedOrUnsuspended(any(Computer::class.java),
-                any(), any(), any())
+        verify(broadcastHelper).sendPackagesSuspendedOrUnsuspendedForUser(
+                any(), eq(Intent.ACTION_PACKAGES_UNSUSPENDED),
+                pkgListCaptor.capture(), any(), any(), any())
+        verify(broadcastHelper).sendMyPackageSuspendedOrUnsuspended(
+                any(), any(), any(), any())
 
         var modifiedPackages = pkgListCaptor.value
         assertThat(modifiedPackages).asList().containsExactly(TEST_PACKAGE_1, TEST_PACKAGE_2)
@@ -230,10 +230,10 @@
 
         testHandler.flush()
         verify(pms, times(2)).scheduleWritePackageRestrictions(eq(TEST_USER_ID))
-        verify(broadcastHelper).sendPackagesSuspendedOrUnsuspendedForUser(any(Computer::class.java),
-                eq(Intent.ACTION_PACKAGES_UNSUSPENDED), any(), any(), any(), any())
-        verify(broadcastHelper).sendMyPackageSuspendedOrUnsuspended(any(Computer::class.java),
-                any(), any(), any())
+        verify(broadcastHelper).sendPackagesSuspendedOrUnsuspendedForUser(
+                any(), eq(Intent.ACTION_PACKAGES_UNSUSPENDED), any(), any(), any(), any())
+        verify(broadcastHelper).sendMyPackageSuspendedOrUnsuspended(
+                any(), any(), any(), any())
 
         assertThat(suspendPackageHelper.getSuspendingPackage(pms.snapshotComputer(),
             TEST_PACKAGE_1, TEST_USER_ID, deviceOwnerUid)).isNull()
diff --git a/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java b/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
index 7248833..b166514 100644
--- a/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
+++ b/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
@@ -64,6 +64,7 @@
 import android.os.CpuHeadroomParamsInternal;
 import android.os.GpuHeadroomParamsInternal;
 import android.os.IBinder;
+import android.os.IHintManager;
 import android.os.IHintSession;
 import android.os.PerformanceHintManager;
 import android.os.Process;
@@ -154,6 +155,8 @@
     private ActivityManagerInternal mAmInternalMock;
     @Mock
     private PackageManager mMockPackageManager;
+    @Mock
+    private IHintManager.IHintManagerClient mClientCallback;
     @Rule
     public final CheckFlagsRule mCheckFlagsRule =
             DeviceFlagsValueProvider.createCheckFlagsRule();
@@ -171,6 +174,23 @@
         };
     }
 
+    private SupportInfo makeDefaultSupportInfo() {
+        mSupportInfo = new SupportInfo();
+        mSupportInfo.usesSessions = true;
+        // By default, mark everything as fully supported
+        mSupportInfo.sessionHints = -1;
+        mSupportInfo.sessionModes = -1;
+        mSupportInfo.modes = -1;
+        mSupportInfo.boosts = -1;
+        mSupportInfo.sessionTags = -1;
+        mSupportInfo.headroom = new SupportInfo.HeadroomSupportInfo();
+        mSupportInfo.headroom.isCpuSupported = true;
+        mSupportInfo.headroom.cpuMinIntervalMillis = 2000;
+        mSupportInfo.headroom.isGpuSupported = true;
+        mSupportInfo.headroom.gpuMinIntervalMillis = 2000;
+        return mSupportInfo;
+    }
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -181,12 +201,7 @@
         mConfig.eventFlagDescriptor = new MQDescriptor<Byte, Byte>();
         ApplicationInfo applicationInfo = new ApplicationInfo();
         applicationInfo.category = ApplicationInfo.CATEGORY_GAME;
-        mSupportInfo = new SupportInfo();
-        mSupportInfo.headroom = new SupportInfo.HeadroomSupportInfo();
-        mSupportInfo.headroom.isCpuSupported = true;
-        mSupportInfo.headroom.cpuMinIntervalMillis = 2000;
-        mSupportInfo.headroom.isGpuSupported = true;
-        mSupportInfo.headroom.gpuMinIntervalMillis = 2000;
+        mSupportInfo = makeDefaultSupportInfo();
         when(mContext.getPackageManager()).thenReturn(mMockPackageManager);
         when(mMockPackageManager.getNameForUid(anyInt())).thenReturn(TEST_APP_NAME);
         when(mMockPackageManager.getApplicationInfo(eq(TEST_APP_NAME), anyInt()))
@@ -215,6 +230,7 @@
         when(mIPowerMock.getInterfaceVersion()).thenReturn(6);
         when(mIPowerMock.getSupportInfo()).thenReturn(mSupportInfo);
         when(mIPowerMock.getSessionChannel(anyInt(), anyInt())).thenReturn(mConfig);
+        when(mIPowerMock.getSupportInfo()).thenReturn(mSupportInfo);
         LocalServices.removeServiceForTest(ActivityManagerInternal.class);
         LocalServices.addService(ActivityManagerInternal.class, mAmInternalMock);
     }
@@ -409,8 +425,11 @@
         HintManagerService service = createService();
         IBinder token = new Binder();
 
-        final int threadCount =
-                service.getBinderServiceInstance().getMaxGraphicsPipelineThreadsCount();
+        IHintManager.HintManagerClientData data = service.getBinderServiceInstance()
+                .registerClient(mClientCallback);
+
+        final int threadCount = data.maxGraphicsPipelineThreads;
+
         long sessionPtr1 = 1111L;
         long sessionId1 = 11111L;
         CountDownLatch stopLatch1 = new CountDownLatch(1);
@@ -1400,4 +1419,67 @@
         verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams1));
         verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams2));
     }
+
+    @Test
+    public void testRegisteringClient() throws Exception {
+        HintManagerService service = createService();
+        IHintManager.HintManagerClientData data = service.getBinderServiceInstance()
+                .registerClient(mClientCallback);
+        assertNotNull(data);
+        assertEquals(data.supportInfo, mSupportInfo);
+    }
+
+    @Test
+    public void testRegisteringClientOnV4() throws Exception {
+        when(mIPowerMock.getInterfaceVersion()).thenReturn(4);
+        HintManagerService service = createService();
+        IHintManager.HintManagerClientData data = service.getBinderServiceInstance()
+                .registerClient(mClientCallback);
+        assertNotNull(data);
+        assertEquals(data.supportInfo.usesSessions, true);
+        assertEquals(data.supportInfo.boosts, 0);
+        assertEquals(data.supportInfo.modes, 0);
+        assertEquals(data.supportInfo.sessionHints, 31);
+        assertEquals(data.supportInfo.sessionModes, 0);
+        assertEquals(data.supportInfo.sessionTags, 0);
+        assertEquals(data.powerHalVersion, 4);
+        assertEquals(data.preferredRateNanos, DEFAULT_HINT_PREFERRED_RATE);
+    }
+
+    @Test
+    public void testRegisteringClientOnV5() throws Exception {
+        when(mIPowerMock.getInterfaceVersion()).thenReturn(5);
+        HintManagerService service = createService();
+        IHintManager.HintManagerClientData data = service.getBinderServiceInstance()
+                .registerClient(mClientCallback);
+        assertNotNull(data);
+        assertEquals(data.supportInfo.usesSessions, true);
+        assertEquals(data.supportInfo.boosts, 0);
+        assertEquals(data.supportInfo.modes, 0);
+        assertEquals(data.supportInfo.sessionHints, 255);
+        assertEquals(data.supportInfo.sessionModes, 1);
+        assertEquals(data.supportInfo.sessionTags, 31);
+        assertEquals(data.powerHalVersion, 5);
+        assertEquals(data.preferredRateNanos, DEFAULT_HINT_PREFERRED_RATE);
+    }
+
+    @Test
+    public void testSettingUpOldClientWhenUnsupported() throws Exception {
+        when(mIPowerMock.getInterfaceVersion()).thenReturn(5);
+        // Mock unsupported to modify the default support behavior
+        when(mNativeWrapperMock.halGetHintSessionPreferredRate())
+                .thenReturn(-1L);
+        HintManagerService service = createService();
+        IHintManager.HintManagerClientData data = service.getBinderServiceInstance()
+                .registerClient(mClientCallback);
+        assertNotNull(data);
+        assertEquals(data.supportInfo.usesSessions, false);
+        assertEquals(data.supportInfo.boosts, 0);
+        assertEquals(data.supportInfo.modes, 0);
+        assertEquals(data.supportInfo.sessionHints, 0);
+        assertEquals(data.supportInfo.sessionModes, 0);
+        assertEquals(data.supportInfo.sessionTags, 0);
+        assertEquals(data.powerHalVersion, 5);
+        assertEquals(data.preferredRateNanos, -1);
+    }
 }
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsAggregatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsAggregatorTest.java
index f312bed..3bdbcb5 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsAggregatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsAggregatorTest.java
@@ -263,6 +263,34 @@
         });
     }
 
+    @Test
+    public void emptyHistory() {
+        PowerStats.Descriptor descriptor = new PowerStats.Descriptor(TEST_POWER_COMPONENT,
+                "majorDrain", 1, null, 0, 1, new PersistableBundle());
+        PowerStats powerStats = new PowerStats(descriptor);
+
+        mHistory.forceRecordAllHistory();
+
+        advance(1000);
+
+        long firstItemTimestamp = mMonotonicClock.monotonicTime();
+        powerStats.stats = new long[]{24};
+        mHistory.recordPowerStats(mClock.realtime, mClock.uptime, powerStats);
+
+        advance(1000);
+
+        long secondItemTimestamp = mMonotonicClock.monotonicTime();
+        powerStats.stats = new long[]{42};
+        mHistory.recordPowerStats(mClock.realtime, mClock.uptime, powerStats);
+
+        mAggregator.aggregatePowerStats(mHistory, firstItemTimestamp + 1, secondItemTimestamp,
+                stats -> {
+                    mAggregatedStatsCount++;
+                });
+
+        assertThat(mAggregatedStatsCount).isEqualTo(0);
+    }
+
     private void advance(long durationMs) {
         mClock.realtime += durationMs;
         mClock.uptime += durationMs;
diff --git a/services/tests/servicestests/src/com/android/server/autofill/PresentationEventLoggerTest.java b/services/tests/servicestests/src/com/android/server/autofill/PresentationEventLoggerTest.java
index 75258f0..d2db999 100644
--- a/services/tests/servicestests/src/com/android/server/autofill/PresentationEventLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/autofill/PresentationEventLoggerTest.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.autofill;
 
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SUGGESTION_FILTER_OUT;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_CHANGED;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -129,4 +131,57 @@
         assertThat(event).isNotNull();
         assertThat(event.mDisplayPresentationType).isEqualTo(3);
     }
+
+    @Test
+    public void testNoSuggestionsTextFiltered() {
+        PresentationStatsEventLogger pEventLogger =
+                PresentationStatsEventLogger.createPresentationLog(1, 1, 1);
+        AutofillId id = new AutofillId(13);
+        AutofillValue initialValue = AutofillValue.forText("hello");
+        pEventLogger.startNewEvent();
+        pEventLogger.maybeSetFocusedId(id);
+        pEventLogger.maybeSetNoPresentationEventReasonSuggestionsFiltered(initialValue);
+
+        PresentationStatsEventLogger.PresentationStatsEventInternal event =
+                pEventLogger.getInternalEvent().get();
+        assertThat(event).isNotNull();
+        int NO_SUGGESTIONS =
+                AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SUGGESTION_FILTER_OUT;
+        assertThat(event.mNoPresentationReason).isEqualTo(NO_SUGGESTIONS);
+    }
+
+    @Test
+    public void testSuggestionsTextNotFiltered() {
+        PresentationStatsEventLogger pEventLogger =
+                PresentationStatsEventLogger.createPresentationLog(1, 1, 1);
+        AutofillId id = new AutofillId(13);
+        AutofillValue initialValue = null;
+        pEventLogger.startNewEvent();
+        pEventLogger.maybeSetFocusedId(id);
+        pEventLogger.maybeSetNoPresentationEventReasonSuggestionsFiltered(initialValue);
+
+        PresentationStatsEventLogger.PresentationStatsEventInternal event =
+                pEventLogger.getInternalEvent().get();
+        assertThat(event).isNotNull();
+        assertThat(event.mNoPresentationReason).isNotEqualTo(
+                AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SUGGESTION_FILTER_OUT);
+    }
+
+    @Test
+    public void testNotShownReasonNotOverridden() {
+
+        PresentationStatsEventLogger pEventLogger =
+                PresentationStatsEventLogger.createPresentationLog(1, 1, 1);
+
+        pEventLogger.startNewEvent();
+        pEventLogger.maybeSetNoPresentationEventReason(AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_CHANGED);
+        // Not allowed - no op
+        pEventLogger.maybeSetNoPresentationEventReasonIfNoReasonExists(
+                AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SUGGESTION_FILTER_OUT);
+
+        PresentationStatsEventLogger.PresentationStatsEventInternal event =
+                pEventLogger.getInternalEvent().get();
+        assertThat(event).isNotNull();
+        assertThat(event.mNoPresentationReason).isEqualTo(AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_CHANGED);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
index 5127b2d..c6df146 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
@@ -22,6 +22,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertEquals;
@@ -921,6 +923,41 @@
         });
     }
 
+    @Test
+    public void shouldShowRdmEduDialog1() {
+        // RDM V1 Cases
+        assertTrue(DeviceStateManagerService.shouldShowRdmEduDialog(
+                false /* hasControlDeviceStatePermission */,
+                false /* requestingRdmOuterDefault */,
+                false /* isDeviceClosed (no-op) */));
+
+        assertFalse(DeviceStateManagerService.shouldShowRdmEduDialog(
+                true /* hasControlDeviceStatePermission */,
+                false /* requestingRdmOuterDefault */,
+                true /* isDeviceClosed (no-op) */));
+
+        // RDM V2 Cases
+        // hasControlDeviceStatePermission = false
+        assertFalse(DeviceStateManagerService.shouldShowRdmEduDialog(
+                false /* hasControlDeviceStatePermission */,
+                true /* requestingRdmOuterDefault */,
+                false /* isDeviceClosed */));
+        assertTrue(DeviceStateManagerService.shouldShowRdmEduDialog(
+                false /* hasControlDeviceStatePermission */,
+                true /* requestingRdmOuterDefault */,
+                true /* isDeviceClosed */));
+
+        // hasControlDeviceStatePermission = true
+        assertFalse(DeviceStateManagerService.shouldShowRdmEduDialog(
+                true /* hasControlDeviceStatePermission */,
+                true /* requestingRdmOuterDefault */,
+                false /* isDeviceClosed */));
+        assertFalse(DeviceStateManagerService.shouldShowRdmEduDialog(
+                true /* hasControlDeviceStatePermission */,
+                true /* requestingRdmOuterDefault */,
+                true /* isDeviceClosed */));
+    }
+
     /**
      * Common code to verify the handling of FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP flag.
      *
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index a0f2395..d70ffd2 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -159,7 +159,7 @@
     /**
      * Test for the first launch path, no settings file available.
      */
-    public void testFirstInitialize() {
+    public void FirstInitialize() {
         assertResetTimes(START_TIME, START_TIME + INTERVAL);
     }
 
@@ -167,7 +167,7 @@
      * Test for {@link ShortcutService#getLastResetTimeLocked()} and
      * {@link ShortcutService#getNextResetTimeLocked()}.
      */
-    public void testUpdateAndGetNextResetTimeLocked() {
+    public void UpdateAndGetNextResetTimeLocked() {
         assertResetTimes(START_TIME, START_TIME + INTERVAL);
 
         // Advance clock.
@@ -196,7 +196,7 @@
     /**
      * Test for the restoration from saved file.
      */
-    public void testInitializeFromSavedFile() {
+    public void InitializeFromSavedFile() {
 
         mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL + 50;
         assertResetTimes(START_TIME + 4 * INTERVAL, START_TIME + 5 * INTERVAL);
@@ -220,7 +220,7 @@
         // TODO Add various broken cases.
     }
 
-    public void testLoadConfig() {
+    public void LoadConfig() {
         mService.updateConfigurationLocked(
                 ConfigConstants.KEY_RESET_INTERVAL_SEC + "=123,"
                         + ConfigConstants.KEY_MAX_SHORTCUTS + "=4,"
@@ -261,22 +261,22 @@
     // === Test for app side APIs ===
 
     /** Test for {@link android.content.pm.ShortcutManager#getMaxShortcutCountForActivity()} */
-    public void testGetMaxDynamicShortcutCount() {
+    public void GetMaxDynamicShortcutCount() {
         assertEquals(MAX_SHORTCUTS, mManager.getMaxShortcutCountForActivity());
     }
 
     /** Test for {@link android.content.pm.ShortcutManager#getRemainingCallCount()} */
-    public void testGetRemainingCallCount() {
+    public void GetRemainingCallCount() {
         assertEquals(MAX_UPDATES_PER_INTERVAL, mManager.getRemainingCallCount());
     }
 
-    public void testGetIconMaxDimensions() {
+    public void GetIconMaxDimensions() {
         assertEquals(MAX_ICON_DIMENSION, mManager.getIconMaxWidth());
         assertEquals(MAX_ICON_DIMENSION, mManager.getIconMaxHeight());
     }
 
     /** Test for {@link android.content.pm.ShortcutManager#getRateLimitResetTime()} */
-    public void testGetRateLimitResetTime() {
+    public void GetRateLimitResetTime() {
         assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
 
         mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL + 50;
@@ -284,7 +284,7 @@
         assertEquals(START_TIME + 5 * INTERVAL, mManager.getRateLimitResetTime());
     }
 
-    public void testSetDynamicShortcuts() {
+    public void SetDynamicShortcuts() {
         setCaller(CALLING_PACKAGE_1, USER_0);
 
         final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.icon1);
@@ -354,7 +354,7 @@
         });
     }
 
-    public void testAddDynamicShortcuts() {
+    public void AddDynamicShortcuts() {
         setCaller(CALLING_PACKAGE_1, USER_0);
 
         final ShortcutInfo si1 = makeShortcut("shortcut1");
@@ -402,7 +402,7 @@
         });
     }
 
-    public void testPushDynamicShortcut() {
+    public void PushDynamicShortcut() {
         // Change the max number of shortcuts.
         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=5,"
                 + ShortcutService.ConfigConstants.KEY_SAVE_DELAY_MILLIS + "=1");
@@ -543,7 +543,7 @@
                 eq(CALLING_PACKAGE_1), eq("s9"), eq(USER_0));
     }
 
-    public void testPushDynamicShortcut_CallsToUsageStatsManagerAreThrottled()
+    public void PushDynamicShortcut_CallsToUsageStatsManagerAreThrottled()
             throws InterruptedException {
         mService.updateConfigurationLocked(
                 ShortcutService.ConfigConstants.KEY_SAVE_DELAY_MILLIS + "=500");
@@ -594,7 +594,7 @@
                 eq(CALLING_PACKAGE_2), any(), eq(USER_0));
     }
 
-    public void testUnlimitedCalls() {
+    public void UnlimitedCalls() {
         setCaller(CALLING_PACKAGE_1, USER_0);
 
         final ShortcutInfo si1 = makeShortcut("shortcut1");
@@ -625,7 +625,7 @@
         assertEquals(3, mManager.getRemainingCallCount());
     }
 
-    public void testPublishWithNoActivity() {
+    public void PublishWithNoActivity() {
         // If activity is not explicitly set, use the default one.
 
         mRunningUsers.put(USER_10, true);
@@ -731,7 +731,7 @@
         });
     }
 
-    public void testPublishWithNoActivity_noMainActivityInPackage() {
+    public void PublishWithNoActivity_noMainActivityInPackage() {
         mRunningUsers.put(USER_10, true);
 
         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
@@ -750,7 +750,7 @@
         });
     }
 
-    public void testDeleteDynamicShortcuts() {
+    public void DeleteDynamicShortcuts() {
         final ShortcutInfo si1 = makeShortcut("shortcut1");
         final ShortcutInfo si2 = makeShortcut("shortcut2");
         final ShortcutInfo si3 = makeShortcut("shortcut3");
@@ -791,7 +791,7 @@
         assertEquals(2, mManager.getRemainingCallCount());
     }
 
-    public void testDeleteAllDynamicShortcuts() {
+    public void DeleteAllDynamicShortcuts() {
         final ShortcutInfo si1 = makeShortcut("shortcut1");
         final ShortcutInfo si2 = makeShortcut("shortcut2");
         final ShortcutInfo si3 = makeShortcut("shortcut3");
@@ -820,7 +820,7 @@
         assertEquals(1, mManager.getRemainingCallCount());
     }
 
-    public void testIcons() throws IOException {
+    public void Icons() throws IOException {
         final Icon res32x32 = Icon.createWithResource(getTestContext(), R.drawable.black_32x32);
         final Icon res64x64 = Icon.createWithResource(getTestContext(), R.drawable.black_64x64);
         final Icon res512x512 = Icon.createWithResource(getTestContext(), R.drawable.black_512x512);
@@ -1034,7 +1034,7 @@
 */
     }
 
-    public void testCleanupDanglingBitmaps() throws Exception {
+    public void CleanupDanglingBitmaps() throws Exception {
         assertBitmapDirectories(USER_0, EMPTY_STRINGS);
         assertBitmapDirectories(USER_10, EMPTY_STRINGS);
 
@@ -1203,7 +1203,7 @@
                         maxSize));
     }
 
-    public void testShrinkBitmap() {
+    public void ShrinkBitmap() {
         checkShrinkBitmap(32, 32, R.drawable.black_512x512, 32);
         checkShrinkBitmap(511, 511, R.drawable.black_512x512, 511);
         checkShrinkBitmap(512, 512, R.drawable.black_512x512, 512);
@@ -1226,7 +1226,7 @@
         return out.getFile();
     }
 
-    public void testOpenIconFileForWrite() throws IOException {
+    public void OpenIconFileForWrite() throws IOException {
         mInjectedCurrentTimeMillis = 1000;
 
         final File p10_1_1 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1);
@@ -1300,7 +1300,7 @@
         assertFalse(p11_1_3.getName().contains("_"));
     }
 
-    public void testUpdateShortcuts() {
+    public void UpdateShortcuts() {
         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
                     makeShortcut("s1"),
@@ -1431,7 +1431,7 @@
         });
     }
 
-    public void testUpdateShortcuts_icons() {
+    public void UpdateShortcuts_icons() {
         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
                     makeShortcut("s1")
@@ -1525,7 +1525,7 @@
         });
     }
 
-    public void testShortcutManagerGetShortcuts_shortcutTypes() {
+    public void ShortcutManagerGetShortcuts_shortcutTypes() {
 
         // Create 3 manifest and 3 dynamic shortcuts
         addManifestShortcutResource(
@@ -1616,7 +1616,7 @@
         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED), "s1", "s2");
     }
 
-    public void testCachedShortcuts() {
+    public void CachedShortcuts() {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
                     makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"),
@@ -1700,7 +1700,7 @@
                 "s2");
     }
 
-    public void testCachedShortcuts_accessShortcutsPermission() {
+    public void CachedShortcuts_accessShortcutsPermission() {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
                     makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"),
@@ -1742,7 +1742,7 @@
         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED), "s3");
     }
 
-    public void testCachedShortcuts_canPassShortcutLimit() {
+    public void CachedShortcuts_canPassShortcutLimit() {
         // Change the max number of shortcuts.
         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=4");
 
@@ -1780,7 +1780,7 @@
 
     // === Test for launcher side APIs ===
 
-    public void testGetShortcuts() {
+    public void GetShortcuts() {
 
         // Set up shortcuts.
 
@@ -1997,7 +1997,7 @@
                 "s1", "s3");
     }
 
-    public void testGetShortcuts_shortcutKinds() throws Exception {
+    public void GetShortcuts_shortcutKinds() throws Exception {
         // Create 3 manifest and 3 dynamic shortcuts
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
@@ -2108,7 +2108,7 @@
         });
     }
 
-    public void testGetShortcuts_resolveStrings() throws Exception {
+    public void GetShortcuts_resolveStrings() throws Exception {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             ShortcutInfo si = new ShortcutInfo.Builder(mClientContext)
                     .setId("id")
@@ -2156,7 +2156,7 @@
         });
     }
 
-    public void testGetShortcuts_personsFlag() {
+    public void GetShortcuts_personsFlag() {
         ShortcutInfo s = new ShortcutInfo.Builder(mClientContext, "id")
                 .setShortLabel("label")
                 .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
@@ -2204,7 +2204,7 @@
     }
 
     // TODO resource
-    public void testGetShortcutInfo() {
+    public void GetShortcutInfo() {
         // Create shortcuts.
         setCaller(CALLING_PACKAGE_1);
         final ShortcutInfo s1_1 = makeShortcut(
@@ -2279,7 +2279,7 @@
         assertEquals("ABC", findById(list, "s1").getTitle());
     }
 
-    public void testPinShortcutAndGetPinnedShortcuts() {
+    public void PinShortcutAndGetPinnedShortcuts() {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             final ShortcutInfo s1_1 = makeShortcutWithTimestamp("s1", 1000);
             final ShortcutInfo s1_2 = makeShortcutWithTimestamp("s2", 2000);
@@ -2360,7 +2360,7 @@
      * This is similar to the above test, except it used "disable" instead of "remove".  It also
      * does "enable".
      */
-    public void testDisableAndEnableShortcuts() {
+    public void DisableAndEnableShortcuts() {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             final ShortcutInfo s1_1 = makeShortcutWithTimestamp("s1", 1000);
             final ShortcutInfo s1_2 = makeShortcutWithTimestamp("s2", 2000);
@@ -2485,7 +2485,7 @@
         });
     }
 
-    public void testDisableShortcuts_thenRepublish() {
+    public void DisableShortcuts_thenRepublish() {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
@@ -2555,7 +2555,7 @@
         });
     }
 
-    public void testPinShortcutAndGetPinnedShortcuts_multi() {
+    public void PinShortcutAndGetPinnedShortcuts_multi() {
         // Create some shortcuts.
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
@@ -2831,7 +2831,7 @@
         });
     }
 
-    public void testPinShortcutAndGetPinnedShortcuts_assistant() {
+    public void PinShortcutAndGetPinnedShortcuts_assistant() {
         // Create some shortcuts.
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
@@ -2887,7 +2887,7 @@
         });
     }
 
-    public void testPinShortcutAndGetPinnedShortcuts_crossProfile_plusLaunch() {
+    public void PinShortcutAndGetPinnedShortcuts_crossProfile_plusLaunch() {
         // Create some shortcuts.
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
@@ -3476,7 +3476,7 @@
         });
     }
 
-    public void testStartShortcut() {
+    public void StartShortcut() {
         // Create some shortcuts.
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             final ShortcutInfo s1_1 = makeShortcut(
@@ -3611,7 +3611,7 @@
         // TODO Check extra, etc
     }
 
-    public void testLauncherCallback() throws Throwable {
+    public void LauncherCallback() throws Throwable {
         // Disable throttling for this test.
         mService.updateConfigurationLocked(
                 ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL + "=99999999,"
@@ -3777,7 +3777,7 @@
                 .isEmpty();
     }
 
-    public void testLauncherCallback_crossProfile() throws Throwable {
+    public void LauncherCallback_crossProfile() throws Throwable {
         prepareCrossProfileDataSet();
 
         final Handler h = new Handler(Looper.getMainLooper());
@@ -3900,7 +3900,7 @@
 
     // === Test for persisting ===
 
-    public void testSaveAndLoadUser_empty() {
+    public void SaveAndLoadUser_empty() {
         assertTrue(mManager.setDynamicShortcuts(list()));
 
         Log.i(TAG, "Saved state");
@@ -3917,7 +3917,7 @@
     /**
      * Try save and load, also stop/start the user.
      */
-    public void testSaveAndLoadUser() {
+    public void SaveAndLoadUser() {
         // First, create some shortcuts and save.
         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
             final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_64x16);
@@ -4058,7 +4058,7 @@
         // TODO Check all other fields
     }
 
-    public void testLoadCorruptedShortcuts() throws Exception {
+    public void LoadCorruptedShortcuts() throws Exception {
         initService();
 
         addPackage("com.android.chrome", 0, 0);
@@ -4072,7 +4072,7 @@
         assertNull(ShortcutPackage.loadFromFile(mService, user, corruptedShortcutPackage, false));
     }
 
-    public void testSaveCorruptAndLoadUser() throws Exception {
+    public void SaveCorruptAndLoadUser() throws Exception {
         // First, create some shortcuts and save.
         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
             final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_64x16);
@@ -4228,7 +4228,7 @@
         // TODO Check all other fields
     }
 
-    public void testCleanupPackage() {
+    public void CleanupPackage() {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
                     makeShortcut("s0_1"))));
@@ -4505,7 +4505,7 @@
         mService.saveDirtyInfo();
     }
 
-    public void testCleanupPackage_republishManifests() {
+    public void CleanupPackage_republishManifests() {
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_2);
@@ -4573,7 +4573,7 @@
         });
     }
 
-    public void testHandleGonePackage_crossProfile() {
+    public void HandleGonePackage_crossProfile() {
         // Create some shortcuts.
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
@@ -4845,7 +4845,7 @@
         assertEquals(expected, spi.canRestoreTo(mService, pi, true));
     }
 
-    public void testCanRestoreTo() {
+    public void CanRestoreTo() {
         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sig1");
         addPackage(CALLING_PACKAGE_2, CALLING_UID_2, 10, "sig1", "sig2");
         addPackage(CALLING_PACKAGE_3, CALLING_UID_3, 10, "sig1");
@@ -4908,7 +4908,7 @@
         checkCanRestoreTo(DISABLED_REASON_BACKUP_NOT_SUPPORTED, spi3, true, 10, true, "sig1");
     }
 
-    public void testHandlePackageDelete() {
+    public void HandlePackageDelete() {
         checkHandlePackageDeleteInner((userId, packageName) -> {
             uninstallPackage(userId, packageName);
             mService.mPackageMonitor.onReceive(getTestContext(),
@@ -4916,7 +4916,7 @@
         });
     }
 
-    public void testHandlePackageDisable() {
+    public void HandlePackageDisable() {
         checkHandlePackageDeleteInner((userId, packageName) -> {
             disablePackage(userId, packageName);
             mService.mPackageMonitor.onReceive(getTestContext(),
@@ -5048,7 +5048,7 @@
     }
 
     /** Almost ame as testHandlePackageDelete, except it doesn't uninstall packages. */
-    public void testHandlePackageClearData() {
+    public void HandlePackageClearData() {
         final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
                 getTestContext().getResources(), R.drawable.black_32x32));
         setCaller(CALLING_PACKAGE_1, USER_0);
@@ -5124,7 +5124,7 @@
         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
     }
 
-    public void testHandlePackageClearData_manifestRepublished() {
+    public void HandlePackageClearData_manifestRepublished() {
 
         mRunningUsers.put(USER_10, true);
 
@@ -5166,7 +5166,7 @@
         });
     }
 
-    public void testHandlePackageUpdate() throws Throwable {
+    public void HandlePackageUpdate() throws Throwable {
         // Set up shortcuts and launchers.
 
         final Icon res32x32 = Icon.createWithResource(getTestContext(), R.drawable.black_32x32);
@@ -5340,7 +5340,7 @@
     /**
      * Test the case where an updated app has resource IDs changed.
      */
-    public void testHandlePackageUpdate_resIdChanged() throws Exception {
+    public void HandlePackageUpdate_resIdChanged() throws Exception {
         final Icon icon1 = Icon.createWithResource(getTestContext(), /* res ID */ 1000);
         final Icon icon2 = Icon.createWithResource(getTestContext(), /* res ID */ 1001);
 
@@ -5415,7 +5415,7 @@
         });
     }
 
-    public void testHandlePackageUpdate_systemAppUpdate() {
+    public void HandlePackageUpdate_systemAppUpdate() {
 
         // Package1 is a system app.  Package 2 is not a system app, so it's not scanned
         // in this test at all.
@@ -5521,7 +5521,7 @@
                 mService.getUserShortcutsLocked(USER_0).getLastAppScanOsFingerprint());
     }
 
-    public void testHandlePackageChanged() {
+    public void HandlePackageChanged() {
         final ComponentName ACTIVITY1 = new ComponentName(CALLING_PACKAGE_1, "act1");
         final ComponentName ACTIVITY2 = new ComponentName(CALLING_PACKAGE_1, "act2");
 
@@ -5651,7 +5651,7 @@
         });
     }
 
-    public void testHandlePackageUpdate_activityNoLongerMain() throws Throwable {
+    public void HandlePackageUpdate_activityNoLongerMain() throws Throwable {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
                     makeShortcutWithActivity("s1a",
@@ -5737,7 +5737,7 @@
      * - Unpinned dynamic shortcuts
      * - Bitmaps
      */
-    public void testBackupAndRestore() {
+    public void BackupAndRestore() {
 
         assertFileNotExists("user-0/shortcut_dump/restore-0-start.txt");
         assertFileNotExists("user-0/shortcut_dump/restore-1-payload.xml");
@@ -5758,7 +5758,7 @@
         checkBackupAndRestore_success(/*firstRestore=*/ true);
     }
 
-    public void testBackupAndRestore_backupRestoreTwice() {
+    public void BackupAndRestore_backupRestoreTwice() {
         prepareForBackupTest();
 
         checkBackupAndRestore_success(/*firstRestore=*/ true);
@@ -5774,7 +5774,7 @@
         checkBackupAndRestore_success(/*firstRestore=*/ false);
     }
 
-    public void testBackupAndRestore_restoreToNewVersion() {
+    public void BackupAndRestore_restoreToNewVersion() {
         prepareForBackupTest();
 
         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 2);
@@ -5783,7 +5783,7 @@
         checkBackupAndRestore_success(/*firstRestore=*/ true);
     }
 
-    public void testBackupAndRestore_restoreToSuperSetSignatures() {
+    public void BackupAndRestore_restoreToSuperSetSignatures() {
         prepareForBackupTest();
 
         // Change package signatures.
@@ -5980,7 +5980,7 @@
         });
     }
 
-    public void testBackupAndRestore_publisherWrongSignature() {
+    public void BackupAndRestore_publisherWrongSignature() {
         prepareForBackupTest();
 
         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sigx"); // different signature
@@ -5988,7 +5988,7 @@
         checkBackupAndRestore_publisherNotRestored(ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH);
     }
 
-    public void testBackupAndRestore_publisherNoLongerBackupTarget() {
+    public void BackupAndRestore_publisherNoLongerBackupTarget() {
         prepareForBackupTest();
 
         updatePackageInfo(CALLING_PACKAGE_1,
@@ -6117,7 +6117,7 @@
         });
     }
 
-    public void testBackupAndRestore_launcherLowerVersion() {
+    public void BackupAndRestore_launcherLowerVersion() {
         prepareForBackupTest();
 
         addPackage(LAUNCHER_1, LAUNCHER_UID_1, 0); // Lower version
@@ -6126,7 +6126,7 @@
         checkBackupAndRestore_success(/*firstRestore=*/ true);
     }
 
-    public void testBackupAndRestore_launcherWrongSignature() {
+    public void BackupAndRestore_launcherWrongSignature() {
         prepareForBackupTest();
 
         addPackage(LAUNCHER_1, LAUNCHER_UID_1, 10, "sigx"); // different signature
@@ -6134,7 +6134,7 @@
         checkBackupAndRestore_launcherNotRestored(true);
     }
 
-    public void testBackupAndRestore_launcherNoLongerBackupTarget() {
+    public void BackupAndRestore_launcherNoLongerBackupTarget() {
         prepareForBackupTest();
 
         updatePackageInfo(LAUNCHER_1,
@@ -6239,7 +6239,7 @@
         });
     }
 
-    public void testBackupAndRestore_launcherAndPackageNoLongerBackupTarget() {
+    public void BackupAndRestore_launcherAndPackageNoLongerBackupTarget() {
         prepareForBackupTest();
 
         updatePackageInfo(CALLING_PACKAGE_1,
@@ -6337,7 +6337,7 @@
         });
     }
 
-    public void testBackupAndRestore_disabled() {
+    public void BackupAndRestore_disabled() {
         prepareCrossProfileDataSet();
 
         // Before doing backup & restore, disable s1.
@@ -6402,7 +6402,7 @@
     }
 
 
-    public void testBackupAndRestore_manifestRePublished() {
+    public void BackupAndRestore_manifestRePublished() {
         // Publish two manifest shortcuts.
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
@@ -6493,7 +6493,7 @@
      * logcat.
      * - if it has allowBackup=false, we don't touch any of the existing shortcuts.
      */
-    public void testBackupAndRestore_appAlreadyInstalledWhenRestored() {
+    public void BackupAndRestore_appAlreadyInstalledWhenRestored() {
         // Pre-backup.  Same as testBackupAndRestore_manifestRePublished().
 
         // Publish two manifest shortcuts.
@@ -6618,7 +6618,7 @@
     /**
      * Test for restoring the pre-P backup format.
      */
-    public void testBackupAndRestore_api27format() throws Exception {
+    public void BackupAndRestore_api27format() throws Exception {
         final byte[] payload = readTestAsset("shortcut/shortcut_api27_backup.xml").getBytes();
 
         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "22222");
@@ -6656,7 +6656,7 @@
 
     }
 
-    public void testSaveAndLoad_crossProfile() {
+    public void SaveAndLoad_crossProfile() {
         prepareCrossProfileDataSet();
 
         dumpsysOnLogcat("Before save & load");
@@ -6859,7 +6859,7 @@
                         .getPackageUserId());
     }
 
-    public void testOnApplicationActive_permission() {
+    public void OnApplicationActive_permission() {
         assertExpectException(SecurityException.class, "Missing permission", () ->
                 mManager.onApplicationActive(CALLING_PACKAGE_1, USER_0));
 
@@ -6868,7 +6868,7 @@
         mManager.onApplicationActive(CALLING_PACKAGE_1, USER_0);
     }
 
-    public void testGetShareTargets_permission() {
+    public void GetShareTargets_permission() {
         addPackage(CHOOSER_ACTIVITY_PACKAGE, CHOOSER_ACTIVITY_UID, 10, "sig1");
         mInjectedChooserActivity =
                 ComponentName.createRelative(CHOOSER_ACTIVITY_PACKAGE, ".ChooserActivity");
@@ -6887,7 +6887,7 @@
         });
     }
 
-    public void testHasShareTargets_permission() {
+    public void HasShareTargets_permission() {
         assertExpectException(SecurityException.class, "Missing permission", () ->
                 mManager.hasShareTargets(CALLING_PACKAGE_1));
 
@@ -6896,7 +6896,7 @@
         mManager.hasShareTargets(CALLING_PACKAGE_1);
     }
 
-    public void testisSharingShortcut_permission() throws IntentFilter.MalformedMimeTypeException {
+    public void isSharingShortcut_permission() throws IntentFilter.MalformedMimeTypeException {
         setCaller(LAUNCHER_1, USER_0);
 
         IntentFilter filter_any = new IntentFilter();
@@ -6911,18 +6911,18 @@
         mManager.hasShareTargets(CALLING_PACKAGE_1);
     }
 
-    public void testDumpsys_crossProfile() {
+    public void Dumpsys_crossProfile() {
         prepareCrossProfileDataSet();
         dumpsysOnLogcat("test1", /* force= */ true);
     }
 
-    public void testDumpsys_withIcons() throws IOException {
-        testIcons();
+    public void Dumpsys_withIcons() throws IOException {
+        Icons();
         // Dump after having some icons.
         dumpsysOnLogcat("test1", /* force= */ true);
     }
 
-    public void testManifestShortcut_publishOnUnlockUser() {
+    public void ManifestShortcut_publishOnUnlockUser() {
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_1);
@@ -7136,7 +7136,7 @@
         assertNull(mService.getPackageShortcutForTest(LAUNCHER_1, USER_0));
     }
 
-    public void testManifestShortcut_publishOnBroadcast() {
+    public void ManifestShortcut_publishOnBroadcast() {
         // First, no packages are installed.
         uninstallPackage(USER_0, CALLING_PACKAGE_1);
         uninstallPackage(USER_0, CALLING_PACKAGE_2);
@@ -7392,7 +7392,7 @@
         });
     }
 
-    public void testManifestShortcuts_missingMandatoryFields() {
+    public void ManifestShortcuts_missingMandatoryFields() {
         // Start with no apps installed.
         uninstallPackage(USER_0, CALLING_PACKAGE_1);
         uninstallPackage(USER_0, CALLING_PACKAGE_2);
@@ -7461,7 +7461,7 @@
         });
     }
 
-    public void testManifestShortcuts_intentDefinitions() {
+    public void ManifestShortcuts_intentDefinitions() {
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_error_4);
@@ -7603,7 +7603,7 @@
         });
     }
 
-    public void testManifestShortcuts_checkAllFields() {
+    public void ManifestShortcuts_checkAllFields() {
         mService.handleUnlockUser(USER_0);
 
         // Package 1 updated, which has one valid manifest shortcut and one invalid.
@@ -7708,7 +7708,7 @@
         });
     }
 
-    public void testManifestShortcuts_localeChange() throws InterruptedException {
+    public void ManifestShortcuts_localeChange() throws InterruptedException {
         mService.handleUnlockUser(USER_0);
 
         // Package 1 updated, which has one valid manifest shortcut and one invalid.
@@ -7812,7 +7812,7 @@
         });
     }
 
-    public void testManifestShortcuts_updateAndDisabled_notPinned() {
+    public void ManifestShortcuts_updateAndDisabled_notPinned() {
         mService.handleUnlockUser(USER_0);
 
         // First, just publish a manifest shortcut.
@@ -7852,7 +7852,7 @@
         });
     }
 
-    public void testManifestShortcuts_updateAndDisabled_pinned() {
+    public void ManifestShortcuts_updateAndDisabled_pinned() {
         mService.handleUnlockUser(USER_0);
 
         // First, just publish a manifest shortcut.
@@ -7908,7 +7908,7 @@
         });
     }
 
-    public void testManifestShortcuts_duplicateInSingleActivity() {
+    public void ManifestShortcuts_duplicateInSingleActivity() {
         mService.handleUnlockUser(USER_0);
 
         // The XML has two shortcuts with the same ID.
@@ -7933,7 +7933,7 @@
         });
     }
 
-    public void testManifestShortcuts_duplicateInTwoActivities() {
+    public void ManifestShortcuts_duplicateInTwoActivities() {
         mService.handleUnlockUser(USER_0);
 
         // ShortcutActivity has shortcut ms1
@@ -7985,7 +7985,7 @@
     /**
      * Manifest shortcuts cannot override shortcuts that were published via the APIs.
      */
-    public void testManifestShortcuts_cannotOverrideNonManifest() {
+    public void ManifestShortcuts_cannotOverrideNonManifest() {
         mService.handleUnlockUser(USER_0);
 
         // Create a non-pinned dynamic shortcut and a non-dynamic pinned shortcut.
@@ -8058,7 +8058,7 @@
     /**
      * Make sure the APIs won't work on manifest shortcuts.
      */
-    public void testManifestShortcuts_immutable() {
+    public void ManifestShortcuts_immutable() {
         mService.handleUnlockUser(USER_0);
 
         // Create a non-pinned manifest shortcut, a pinned shortcut that was originally
@@ -8151,7 +8151,7 @@
     /**
      * Make sure the APIs won't work on manifest shortcuts.
      */
-    public void testManifestShortcuts_tooMany() {
+    public void ManifestShortcuts_tooMany() {
         // Change the max number of shortcuts.
         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
 
@@ -8170,7 +8170,7 @@
         });
     }
 
-    public void testMaxShortcutCount_set() {
+    public void MaxShortcutCount_set() {
         // Change the max number of shortcuts.
         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
 
@@ -8251,7 +8251,7 @@
         });
     }
 
-    public void testMaxShortcutCount_add() {
+    public void MaxShortcutCount_add() {
         // Change the max number of shortcuts.
         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
 
@@ -8378,7 +8378,7 @@
         });
     }
 
-    public void testMaxShortcutCount_update() {
+    public void MaxShortcutCount_update() {
         // Change the max number of shortcuts.
         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
 
@@ -8469,7 +8469,7 @@
         });
     }
 
-    public void testShortcutsPushedOutByManifest() {
+    public void ShortcutsPushedOutByManifest() {
         // Change the max number of shortcuts.
         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
 
@@ -8577,7 +8577,7 @@
         });
     }
 
-    public void testReturnedByServer() {
+    public void ReturnedByServer() {
         // Package 1 updated, with manifest shortcuts.
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
@@ -8623,7 +8623,7 @@
         });
     }
 
-    public void testIsForegroundDefaultLauncher_true() {
+    public void IsForegroundDefaultLauncher_true() {
         final int uid = 1024;
 
         setDefaultLauncher(UserHandle.USER_SYSTEM, "default");
@@ -8633,7 +8633,7 @@
     }
 
 
-    public void testIsForegroundDefaultLauncher_defaultButNotForeground() {
+    public void IsForegroundDefaultLauncher_defaultButNotForeground() {
         final int uid = 1024;
 
         setDefaultLauncher(UserHandle.USER_SYSTEM, "default");
@@ -8642,7 +8642,7 @@
         assertFalse(mInternal.isForegroundDefaultLauncher("default", uid));
     }
 
-    public void testIsForegroundDefaultLauncher_foregroundButNotDefault() {
+    public void IsForegroundDefaultLauncher_foregroundButNotDefault() {
         final int uid = 1024;
 
         setDefaultLauncher(UserHandle.USER_SYSTEM, "default");
@@ -8651,7 +8651,7 @@
         assertFalse(mInternal.isForegroundDefaultLauncher("another", uid));
     }
 
-    public void testParseShareTargetsFromManifest() {
+    public void ParseShareTargetsFromManifest() {
         // These values must exactly match the content of shortcuts_share_targets.xml resource
         List<ShareTargetInfo> expectedValues = new ArrayList<>();
         expectedValues.add(new ShareTargetInfo(
@@ -8703,7 +8703,7 @@
         }
     }
 
-    public void testShareTargetInfo_saveToXml() throws IOException, XmlPullParserException {
+    public void ShareTargetInfo_saveToXml() throws IOException, XmlPullParserException {
         List<ShareTargetInfo> expectedValues = new ArrayList<>();
         expectedValues.add(new ShareTargetInfo(
                 new ShareTargetInfo.TargetData[]{new ShareTargetInfo.TargetData(
@@ -8769,7 +8769,7 @@
         }
     }
 
-    public void testIsSharingShortcut() throws IntentFilter.MalformedMimeTypeException {
+    public void IsSharingShortcut() throws IntentFilter.MalformedMimeTypeException {
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_share_targets);
@@ -8819,7 +8819,7 @@
                 filter_any));
     }
 
-    public void testIsSharingShortcut_PinnedAndCachedOnlyShortcuts()
+    public void IsSharingShortcut_PinnedAndCachedOnlyShortcuts()
             throws IntentFilter.MalformedMimeTypeException {
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
@@ -8876,7 +8876,7 @@
                 filter_any));
     }
 
-    public void testAddingShortcuts_ExcludesHiddenFromLauncherShortcuts() {
+    public void AddingShortcuts_ExcludesHiddenFromLauncherShortcuts() {
         final ShortcutInfo s1 = makeShortcutExcludedFromLauncher("s1");
         final ShortcutInfo s2 = makeShortcutExcludedFromLauncher("s2");
         final ShortcutInfo s3 = makeShortcutExcludedFromLauncher("s3");
@@ -8897,7 +8897,7 @@
         });
     }
 
-    public void testUpdateShortcuts_ExcludesHiddenFromLauncherShortcuts() {
+    public void UpdateShortcuts_ExcludesHiddenFromLauncherShortcuts() {
         final ShortcutInfo s1 = makeShortcut("s1");
         final ShortcutInfo s2 = makeShortcut("s2");
         final ShortcutInfo s3 = makeShortcut("s3");
@@ -8910,7 +8910,7 @@
         });
     }
 
-    public void testPinHiddenShortcuts_ThrowsException() {
+    public void PinHiddenShortcuts_ThrowsException() {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertThrown(IllegalArgumentException.class, () -> {
                 mManager.requestPinShortcut(makeShortcutExcludedFromLauncher("s1"), null);
diff --git a/services/tests/servicestests/src/com/android/server/utils/LazyJniRegistrarTest.java b/services/tests/servicestests/src/com/android/server/utils/LazyJniRegistrarTest.java
new file mode 100644
index 0000000..a2df73b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/utils/LazyJniRegistrarTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.utils;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+@SmallTest
+@Presubmit
+@RunWith(JUnit4.class)
+public class LazyJniRegistrarTest {
+
+    @Test
+    public void testNativeMethodsResolve() throws Exception {
+        // Basic test with a few explicit invocations to make sure methods resolve and don't throw.
+        LazyJniRegistrar.registerConsumerIrService();
+        LazyJniRegistrar.registerGameManagerService();
+        LazyJniRegistrar.registerVrManagerService();
+    }
+
+    @Test
+    public void testAllNativeRegisterMethodsResolve() throws Exception {
+        // Catch-all test to make sure public static register* methods resolve and don't throw.
+        for (Method method : LazyJniRegistrar.class.getDeclaredMethods()) {
+            if (Modifier.isPublic(method.getModifiers())
+                    && Modifier.isStatic(method.getModifiers())
+                    && method.getName().startsWith("register")) {
+                method.invoke(null);
+            }
+        }
+    }
+
+    // TODO(b/302724778): Remove manual JNI load
+    static {
+        System.loadLibrary("servicestestjni");
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/utils/OWNERS b/services/tests/servicestests/src/com/android/server/utils/OWNERS
index f5b19a1..69b9fa2 100644
--- a/services/tests/servicestests/src/com/android/server/utils/OWNERS
+++ b/services/tests/servicestests/src/com/android/server/utils/OWNERS
@@ -1,5 +1,6 @@
 per-file EventLoggerTest.java = file:/platform/frameworks/av:/media/janitors/media_solutions_OWNERS
 per-file EventLoggerTest.java = jmtrivi@google.com
+per-file LazyJniRegistrarTest.java = file:/PERFORMANCE_OWNERS
 
 # Bug component : 158088 = per-file AnrTimer*.java
 per-file AnrTimer*.java = file:/PERFORMANCE_OWNERS
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 074cbb5..1fc0d24 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -311,6 +311,7 @@
 
 import com.android.internal.R;
 import com.android.internal.config.sysui.TestableFlagResolver;
+import com.android.internal.logging.InstanceId;
 import com.android.internal.logging.InstanceIdSequence;
 import com.android.internal.logging.InstanceIdSequenceFake;
 import com.android.internal.messages.nano.SystemMessageProto;
@@ -7637,7 +7638,8 @@
                 mTestNotificationChannel, 1, null, true));
         when(r1.getLifespanMs(anyLong())).thenReturn(234);
 
-        r1.getSbn().setInstanceId(mNotificationInstanceIdSequence.newInstanceId());
+        InstanceId instanceId1 = mNotificationInstanceIdSequence.newInstanceId();
+        r1.getSbn().setInstanceId(instanceId1);
         // Enqueues the notification to be posted, so hasPosted will be false.
         mService.addEnqueuedNotification(r1);
 
@@ -7648,8 +7650,10 @@
                 r1.getSbn().getPackageName(), r1.getKey(), signals, "",
                 r1.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment1);
-        assertTrue(mService.checkLastClassificationChannelLog(false /*hasPosted*/,
-                true /*isAlerting*/, 3 /*TYPE_NEWS*/, 234));
+        assertTrue(mService.checkLastClassificationChannelLog(false /*=hasPosted*/,
+                true /*=isAlerting*/, Adjustment.TYPE_NEWS, 234,
+                NOTIFICATION_ADJUSTED.getId(),
+                instanceId1.getId(), r1.getUid()));
 
         // Set up notifications that will be adjusted
         // This notification starts on a low importance channel, so isAlerting is false.
@@ -7659,7 +7663,8 @@
                 mLowImportanceNotificationChannel, 1, null, true));
         when(r2.getLifespanMs(anyLong())).thenReturn(345);
 
-        r2.getSbn().setInstanceId(mNotificationInstanceIdSequence.newInstanceId());
+        InstanceId instanceId2 = mNotificationInstanceIdSequence.newInstanceId();
+        r2.getSbn().setInstanceId(instanceId2);
         // Adds the notification as already posted, so hasPosted will be true.
         mService.addNotification(r2);
         // The signal is removed when used so it has to be readded.
@@ -7669,15 +7674,19 @@
                 r2.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment2);
         assertTrue(mService.checkLastClassificationChannelLog(true /*hasPosted*/,
-                false /*isAlerting*/, 3 /*TYPE_NEWS*/, 345)); // currently failing
+                false /*isAlerting*/, Adjustment.TYPE_NEWS, 345,
+                NOTIFICATION_ADJUSTED.getId(),
+                instanceId2.getId() /*instance_id*/, r2.getUid()));
 
         signals.putInt(Adjustment.KEY_TYPE, Adjustment.TYPE_PROMOTION);
         Adjustment adjustment3 = new Adjustment(
                 r2.getSbn().getPackageName(), r2.getKey(), signals, "",
                 r2.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment3);
-        assertTrue(mService.checkLastClassificationChannelLog(true /*hasPosted*/,
-                false /*isAlerting*/, 1 /*TYPE_PROMOTION*/, 345));
+        assertTrue(mService.checkLastClassificationChannelLog(true /*=hasPosted*/,
+                false /*=isAlerting*/, Adjustment.TYPE_PROMOTION, 345,
+                NOTIFICATION_ADJUSTED.getId(),
+                instanceId2.getId() /*instance_id*/, r2.getUid()));
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java
index 65ed7b6..934c33b 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java
@@ -19,6 +19,8 @@
 
 import static java.util.concurrent.TimeUnit.HOURS;
 
+import android.service.notification.RateEstimator;
+
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java b/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
index ba91ca2..b434819 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
@@ -16,6 +16,8 @@
 
 package com.android.server.notification;
 
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+
 import android.companion.ICompanionDeviceManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -25,6 +27,7 @@
 
 import com.android.internal.logging.InstanceIdSequence;
 import com.android.server.notification.ManagedServices.ManagedServiceInfo;
+import com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent;
 
 import java.util.HashSet;
 import java.util.Set;
@@ -57,6 +60,9 @@
         public boolean isAlerting;
         public long classification;
         public long lifetime;
+        public long eventId;
+        public long instanceId;
+        public long uid;
     }
     public ClassificationChannelLog  lastClassificationChannelLog = null;
 
@@ -221,20 +227,34 @@
     }
 
     @Override
-    protected void logClassificationChannelAdjustmentReceived(boolean hasPosted, boolean isAlerting,
-                                                              int classification, int lifetimeMs) {
+    protected void logClassificationChannelAdjustmentReceived(NotificationRecord r,
+                                                              boolean hasPosted,
+                                                              int classification) {
+
+        boolean isAlerting = r.getChannel().getImportance() >= IMPORTANCE_DEFAULT;
+        int instanceId = r.getSbn().getInstanceId() == null
+                ? 0 : r.getSbn().getInstanceId().getId();
+        int lifetimeMs = r.getLifespanMs(System.currentTimeMillis());
+        int uid = r.getUid();
+
         lastClassificationChannelLog = new ClassificationChannelLog();
         lastClassificationChannelLog.hasPosted = hasPosted;
         lastClassificationChannelLog.isAlerting = isAlerting;
         lastClassificationChannelLog.classification = classification;
         lastClassificationChannelLog.lifetime = lifetimeMs;
+        lastClassificationChannelLog.eventId =
+                NotificationReportedEvent.NOTIFICATION_ADJUSTED.getId();
+        lastClassificationChannelLog.instanceId = instanceId;
+        lastClassificationChannelLog.uid = uid;
     }
 
     /**
      * Returns true if the last recorded classification channel log has all the values specified.
      */
     public boolean checkLastClassificationChannelLog(boolean hasPosted, boolean isAlerting,
-                                                     int classification, int lifetime) {
+                                                     int classification, int lifetime,
+                                                     int eventId, int instanceId,
+                                                     int uid) {
         if (lastClassificationChannelLog == null) {
             return false;
         }
@@ -242,6 +262,9 @@
         return hasPosted == lastClassificationChannelLog.hasPosted
                 && isAlerting == lastClassificationChannelLog.isAlerting
                 && classification == lastClassificationChannelLog.classification
-                && lifetime == lastClassificationChannelLog.lifetime;
+                && lifetime == lastClassificationChannelLog.lifetime
+                && eventId == lastClassificationChannelLog.eventId
+                && instanceId == lastClassificationChannelLog.instanceId
+                && uid == lastClassificationChannelLog.uid;
     }
 }
diff --git a/services/tests/wmtests/res/xml/bookmarks.xml b/services/tests/wmtests/res/xml/bookmarks.xml
index 787f4e8..cbbbc73 100644
--- a/services/tests/wmtests/res/xml/bookmarks.xml
+++ b/services/tests/wmtests/res/xml/bookmarks.xml
@@ -22,7 +22,7 @@
         androidprv:modifierState="META" />
     <bookmark
         category="android.intent.category.APP_CONTACTS"
-        androidprv:keycode="KEYCODE_C"
+        androidprv:keycode="KEYCODE_P"
         androidprv:modifierState="META" />
     <bookmark
         category="android.intent.category.APP_EMAIL"
@@ -30,21 +30,13 @@
         androidprv:modifierState="META" />
     <bookmark
         category="android.intent.category.APP_CALENDAR"
-        androidprv:keycode="KEYCODE_K"
+        androidprv:keycode="KEYCODE_C"
         androidprv:modifierState="META" />
     <bookmark
         category="android.intent.category.APP_MAPS"
         androidprv:keycode="KEYCODE_M"
         androidprv:modifierState="META" />
     <bookmark
-        category="android.intent.category.APP_MUSIC"
-        androidprv:keycode="KEYCODE_P"
-        androidprv:modifierState="META" />
-    <bookmark
-        role="android.app.role.SMS"
-        androidprv:keycode="KEYCODE_S"
-        androidprv:modifierState="META" />
-    <bookmark
         category="android.intent.category.APP_CALCULATOR"
         androidprv:keycode="KEYCODE_U"
         androidprv:modifierState="META" />
@@ -56,7 +48,7 @@
 
     <bookmark
         category="android.intent.category.APP_CONTACTS"
-        androidprv:keycode="KEYCODE_C"
+        androidprv:keycode="KEYCODE_P"
         androidprv:modifierState="META|SHIFT" />
 
     <bookmark
diff --git a/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java b/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
index 32ba8f5..9d4d94b 100644
--- a/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
@@ -26,12 +26,12 @@
 import static com.android.server.policy.PhoneWindowManager.POWER_VOLUME_UP_BEHAVIOR_MUTE;
 import static com.android.server.policy.PhoneWindowManager.SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL;
 
-import android.hardware.input.InputSettings;
 import android.hardware.input.KeyGestureEvent;
 import android.os.RemoteException;
 import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
+import android.provider.Settings;
 import android.view.KeyEvent;
 
 import androidx.test.filters.MediumTest;
@@ -258,9 +258,9 @@
                 {"EXPLORER key -> Launch Default Browser", new int[]{KeyEvent.KEYCODE_EXPLORER},
                         KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER,
                         KeyEvent.KEYCODE_EXPLORER, 0},
-                {"Meta + C -> Launch Default Contacts", new int[]{META_KEY, KeyEvent.KEYCODE_C},
+                {"Meta + P -> Launch Default Contacts", new int[]{META_KEY, KeyEvent.KEYCODE_P},
                         KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS,
-                        KeyEvent.KEYCODE_C, META_ON},
+                        KeyEvent.KEYCODE_P, META_ON},
                 {"CONTACTS key -> Launch Default Contacts", new int[]{KeyEvent.KEYCODE_CONTACTS},
                         KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS,
                         KeyEvent.KEYCODE_CONTACTS, 0},
@@ -270,15 +270,12 @@
                 {"ENVELOPE key -> Launch Default Email", new int[]{KeyEvent.KEYCODE_ENVELOPE},
                         KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL,
                         KeyEvent.KEYCODE_ENVELOPE, 0},
-                {"Meta + K -> Launch Default Calendar", new int[]{META_KEY, KeyEvent.KEYCODE_K},
+                {"Meta + C -> Launch Default Calendar", new int[]{META_KEY, KeyEvent.KEYCODE_C},
                         KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR,
-                        KeyEvent.KEYCODE_K, META_ON},
+                        KeyEvent.KEYCODE_C, META_ON},
                 {"CALENDAR key -> Launch Default Calendar", new int[]{KeyEvent.KEYCODE_CALENDAR},
                         KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR,
                         KeyEvent.KEYCODE_CALENDAR, 0},
-                {"Meta + P -> Launch Default Music", new int[]{META_KEY, KeyEvent.KEYCODE_P},
-                        KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC,
-                        KeyEvent.KEYCODE_P, META_ON},
                 {"MUSIC key -> Launch Default Music", new int[]{KeyEvent.KEYCODE_MUSIC},
                         KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC,
                         KeyEvent.KEYCODE_MUSIC, 0},
@@ -291,11 +288,7 @@
                         KeyEvent.KEYCODE_CALCULATOR, 0},
                 {"Meta + M -> Launch Default Maps", new int[]{META_KEY, KeyEvent.KEYCODE_M},
                         KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS,
-                        KeyEvent.KEYCODE_M, META_ON},
-                {"Meta + S -> Launch Default Messaging App",
-                        new int[]{META_KEY, KeyEvent.KEYCODE_S},
-                        KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING,
-                        KeyEvent.KEYCODE_S, META_ON}};
+                        KeyEvent.KEYCODE_M, META_ON}};
     }
 
     @Keep
@@ -765,54 +758,57 @@
     }
 
     @Test
-    @EnableFlags({com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_SHORTCUT_CONTROL,
-            com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_STICKY_KEYS_FLAG})
-    public void testKeyGestureToggleStickyKeys() {
+    public void testKeyGestureToggleDoNotDisturb() {
+        mPhoneWindowManager.overrideZenMode(Settings.Global.ZEN_MODE_OFF);
         Assert.assertTrue(
-                sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_STICKY_KEYS));
-        Assert.assertTrue(InputSettings.isAccessibilityStickyKeysEnabled(mContext));
+                sendKeyGestureEventComplete(
+                        KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB));
+        mPhoneWindowManager.assertZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
 
+        mPhoneWindowManager.overrideZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
         Assert.assertTrue(
-                sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_STICKY_KEYS));
-        Assert.assertFalse(InputSettings.isAccessibilityStickyKeysEnabled(mContext));
+                sendKeyGestureEventComplete(
+                        KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB));
+        mPhoneWindowManager.assertZenMode(Settings.Global.ZEN_MODE_OFF);
     }
 
     @Test
-    @EnableFlags({com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_SHORTCUT_CONTROL,
-            com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_SLOW_KEYS_FLAG})
-    public void testKeyGestureToggleSlowKeys() {
-        Assert.assertTrue(
-                sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS));
-        Assert.assertTrue(InputSettings.isAccessibilitySlowKeysEnabled(mContext));
+    public void testLaunchSettingsAndSearchDoesntOpenAnything_withKeyguardOn() {
+        mPhoneWindowManager.overrideKeyguardOn(true);
 
-        Assert.assertTrue(
-                sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS));
-        Assert.assertFalse(InputSettings.isAccessibilitySlowKeysEnabled(mContext));
+        sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS);
+        sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SEARCH);
+
+        mPhoneWindowManager.assertNoActivityLaunched();
     }
 
     @Test
-    @EnableFlags({com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_SHORTCUT_CONTROL,
-            com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_MOUSE_KEYS})
-    public void testKeyGestureToggleMouseKeys() {
-        Assert.assertTrue(
-                sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS));
-        Assert.assertTrue(InputSettings.isAccessibilityMouseKeysEnabled(mContext));
+    public void testLaunchSettingsAndSearchDoesntOpenAnything_withUserSetupIncomplete() {
+        mPhoneWindowManager.overrideIsUserSetupComplete(false);
 
-        Assert.assertTrue(
-                sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS));
-        Assert.assertFalse(InputSettings.isAccessibilityMouseKeysEnabled(mContext));
+        sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS);
+        sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SEARCH);
+
+        mPhoneWindowManager.assertNoActivityLaunched();
     }
 
     @Test
-    @EnableFlags({com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_SHORTCUT_CONTROL,
-            com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_BOUNCE_KEYS_FLAG})
-    public void testKeyGestureToggleBounceKeys() {
-        Assert.assertTrue(
-                sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_BOUNCE_KEYS));
-        Assert.assertTrue(InputSettings.isAccessibilityBounceKeysEnabled(mContext));
+    public void testLaunchAssistantDoesntWork_withKeyguardOn() {
+        mPhoneWindowManager.overrideKeyguardOn(true);
 
-        Assert.assertTrue(
-                sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_BOUNCE_KEYS));
-        Assert.assertFalse(InputSettings.isAccessibilityBounceKeysEnabled(mContext));
+        sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT);
+        sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT);
+
+        mPhoneWindowManager.assertSearchManagerDoesntLaunchAssist();
+    }
+
+    @Test
+    public void testLaunchAssistantDoesntWork_withUserSetupIncomplete() {
+        mPhoneWindowManager.overrideIsUserSetupComplete(false);
+
+        sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT);
+        sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT);
+
+        mPhoneWindowManager.assertSearchManagerDoesntLaunchAssist();
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
index cf5323e..35b077e 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
@@ -26,7 +26,6 @@
 import static android.view.KeyEvent.KEYCODE_ENTER;
 import static android.view.KeyEvent.KEYCODE_H;
 import static android.view.KeyEvent.KEYCODE_J;
-import static android.view.KeyEvent.KEYCODE_K;
 import static android.view.KeyEvent.KEYCODE_M;
 import static android.view.KeyEvent.KEYCODE_META_LEFT;
 import static android.view.KeyEvent.KEYCODE_N;
@@ -67,14 +66,12 @@
         // These shortcuts should align with those defined in
         // services/tests/wmtests/res/xml/bookmarks.xml
         INTENT_SHORTCUTS.append(KEYCODE_U, Intent.CATEGORY_APP_CALCULATOR);
-        INTENT_SHORTCUTS.append(KEYCODE_C, Intent.CATEGORY_APP_CONTACTS);
+        INTENT_SHORTCUTS.append(KEYCODE_P, Intent.CATEGORY_APP_CONTACTS);
         INTENT_SHORTCUTS.append(KEYCODE_E, Intent.CATEGORY_APP_EMAIL);
-        INTENT_SHORTCUTS.append(KEYCODE_K, Intent.CATEGORY_APP_CALENDAR);
+        INTENT_SHORTCUTS.append(KEYCODE_C, Intent.CATEGORY_APP_CALENDAR);
         INTENT_SHORTCUTS.append(KEYCODE_M, Intent.CATEGORY_APP_MAPS);
-        INTENT_SHORTCUTS.append(KEYCODE_P, Intent.CATEGORY_APP_MUSIC);
 
         ROLE_SHORTCUTS.append(KEYCODE_B, RoleManager.ROLE_BROWSER);
-        ROLE_SHORTCUTS.append(KEYCODE_S, RoleManager.ROLE_SMS);
     }
     private static final int ANY_DISPLAY_ID = 123;
 
@@ -109,7 +106,7 @@
         sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_SHIFT_LEFT, KEYCODE_B}, 0);
         mPhoneWindowManager.assertLaunchRole(RoleManager.ROLE_BROWSER);
 
-        sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_SHIFT_LEFT, KEYCODE_C}, 0);
+        sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_SHIFT_LEFT, KEYCODE_P}, 0);
         mPhoneWindowManager.assertLaunchCategory(Intent.CATEGORY_APP_CONTACTS);
 
         sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_SHIFT_LEFT, KEYCODE_J}, 0);
diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
index 9db76d4..285d94d 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -447,6 +447,14 @@
         mTestLooper.dispatchAll();
     }
 
+    void overrideZenMode(int mode) {
+        doReturn(mode).when(mNotificationManager).getZenMode();
+    }
+
+    void assertZenMode(int mode) {
+        verify(mNotificationManager).setZenMode(eq(mode), any(), anyString(), eq(true));
+    }
+
     /**
      * Below functions will override the setting or the policy behavior.
      */
@@ -563,6 +571,10 @@
         doNothing().when(mPhoneWindowManager).launchHomeFromHotKey(anyInt());
     }
 
+    void overrideKeyguardOn(boolean isKeyguardOn) {
+        doReturn(isKeyguardOn).when(mPhoneWindowManager).keyguardOn();
+    }
+
     void overrideIsUserSetupComplete(boolean isCompleted) {
         doReturn(isCompleted).when(mPhoneWindowManager).isUserSetupComplete();
     }
@@ -725,6 +737,11 @@
         verify(mSearchManager).launchAssist(any());
     }
 
+    void assertSearchManagerDoesntLaunchAssist() {
+        mTestLooper.dispatchAll();
+        verify(mSearchManager, never()).launchAssist(any());
+    }
+
     void assertLaunchSystemSettings() {
         mTestLooper.dispatchAll();
         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -929,4 +946,10 @@
         verify(mInputManagerInternal)
                 .handleKeyGestureInKeyGestureController(anyInt(), any(), anyInt(), eq(gestureType));
     }
+
+    void assertNoActivityLaunched() {
+        mTestLooper.dispatchAll();
+        verify(mContext, never()).startActivityAsUser(any(), any(), any());
+        verify(mContext, never()).startActivityAsUser(any(), any());
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index d4a921c..1b0d9dc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -554,6 +554,7 @@
 
     @Test
     public void testSetRequestedOrientationUpdatesConfiguration() throws Exception {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final ActivityRecord activity = new ActivityBuilder(mAtm)
                 .setCreateTask(true)
                 .setConfigChanges(ORIENTATION_CONFIG_CHANGES)
@@ -641,6 +642,7 @@
 
     @Test
     public void ignoreRequestedOrientationForResizableInSplitWindows() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final ActivityRecord activity = createActivityWith2LevelTask();
         final Task task = activity.getTask();
         final Task rootTask = activity.getRootTask();
@@ -685,6 +687,7 @@
 
     @Test
     public void respectRequestedOrientationForNonResizableInSplitWindows() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
         spyOn(tda);
         doReturn(true).when(tda).supportsNonResizableMultiWindow();
@@ -1906,6 +1909,7 @@
 
     @Test
     public void testActivityOnCancelFixedRotationTransform() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final ActivityRecord activity = createActivityWithTask();
         final DisplayRotation displayRotation = activity.mDisplayContent.getDisplayRotation();
         final RemoteDisplayChangeController remoteDisplayChangeController = activity
@@ -2054,6 +2058,7 @@
 
     @Test
     public void testFixedRotationSnapshotStartingWindow() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final ActivityRecord activity = createActivityWithTask();
         // TaskSnapshotSurface requires a fullscreen opaque window.
         final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
@@ -2278,6 +2283,7 @@
     @Test
     public void testSupportsFreeform() {
         final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setComponent(getUniqueComponentName(mContext.getPackageName()))
                 .setCreateTask(true)
                 .setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
                 .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
@@ -2410,6 +2416,7 @@
 
     @Test
     public void testOrientationForScreenOrientationBehind() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final Task task = createTask(mDisplayContent);
         // Activity below
         new ActivityBuilder(mAtm)
@@ -2507,6 +2514,7 @@
     @SetupWindows(addWindows = W_ACTIVITY)
     @Test
     public void testLandscapeSeascapeRotationByApp() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final Task task = new TaskBuilder(mSupervisor)
                 .setDisplay(mDisplayContent).setCreateActivity(true).build();
         final ActivityRecord activity = task.getTopNonFinishingActivity();
@@ -2572,6 +2580,7 @@
     @Test
     @Presubmit
     public void testGetOrientation() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         // ActivityBuilder will resume top activities and cause the activity been added into
         // opening apps list. Since this test is focus on the effect of visible on getting
         // orientation, we skip app transition to avoid interference.
@@ -2663,8 +2672,8 @@
     @Test
     public void testSetOrientation_restrictedByTargetSdk() {
         mSetFlagsRule.enableFlags(Flags.FLAG_UNIVERSAL_RESIZABLE_BY_DEFAULT);
-        mDisplayContent.setIgnoreOrientationRequest(true);
         makeDisplayLargeScreen(mDisplayContent);
+        assertTrue(mDisplayContent.getIgnoreOrientationRequest());
 
         assertSetOrientation(Build.VERSION_CODES.CUR_DEVELOPMENT, CATEGORY_SOCIAL, false);
         assertSetOrientation(Build.VERSION_CODES.CUR_DEVELOPMENT, CATEGORY_GAME, true);
@@ -2702,6 +2711,7 @@
 
     @Test
     public void testRespectTopFullscreenOrientation() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
         final Configuration displayConfig = activity.mDisplayContent.getConfiguration();
         final Configuration activityConfig = activity.getConfiguration();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
index 2a53df9..a7fc10f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
@@ -17,30 +17,23 @@
 package com.android.server.wm;
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.SnapshotPersistQueue.MAX_STORE_QUEUE_DEPTH;
 
 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.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 
-import android.content.ComponentName;
-import android.graphics.ColorSpace;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.hardware.HardwareBuffer;
 import android.platform.test.annotations.Presubmit;
 import android.util.ArraySet;
-import android.view.Surface;
 import android.window.TaskSnapshot;
 
 import androidx.test.filters.SmallTest;
@@ -61,14 +54,20 @@
 @SmallTest
 @Presubmit
 @RunWith(WindowTestRunner.class)
-public class ActivitySnapshotControllerTests extends WindowTestsBase {
+public class ActivitySnapshotControllerTests extends TaskSnapshotPersisterTestBase {
 
     private ActivitySnapshotController mActivitySnapshotController;
 
+    public ActivitySnapshotControllerTests() {
+        super(0.8f /* highResScale */, 0.5f /* lowResScale */);
+    }
+
+    @Override
     @Before
-    public void setUp() throws Exception {
-        spyOn(mWm.mSnapshotController.mActivitySnapshotController);
-        mActivitySnapshotController = mWm.mSnapshotController.mActivitySnapshotController;
+    public void setUp() {
+        super.setUp();
+        mActivitySnapshotController = new ActivitySnapshotController(mWm, mSnapshotPersistQueue);
+        spyOn(mActivitySnapshotController);
         doReturn(false).when(mActivitySnapshotController).shouldDisableSnapshots();
         mActivitySnapshotController.resetTmpFields();
     }
@@ -92,12 +91,11 @@
         assertEquals(0, mActivitySnapshotController.mPendingRemoveActivity.size());
         mActivitySnapshotController.resetTmpFields();
 
-        // simulate three activity
+        // simulate three activity, the bottom activity won't participate in transition
         final WindowState belowClose = createAppWindow(task, ACTIVITY_TYPE_STANDARD,
                 "belowClose");
         belowClose.mActivityRecord.commitVisibility(
                 false /* visible */, true /* performLayout */);
-        windows.add(belowClose.mActivityRecord);
         mActivitySnapshotController.handleTransitionFinish(windows);
         assertEquals(1, mActivitySnapshotController.mPendingRemoveActivity.size());
         assertEquals(belowClose.mActivityRecord,
@@ -249,15 +247,28 @@
         assertEquals(taskSnapshot, mActivitySnapshotController.getSnapshot(activities));
     }
 
-    private TaskSnapshot createSnapshot() {
-        HardwareBuffer buffer = mock(HardwareBuffer.class);
-        doReturn(100).when(buffer).getWidth();
-        doReturn(100).when(buffer).getHeight();
-        return new TaskSnapshot(1, 0 /* captureTime */, new ComponentName("", ""), buffer,
-                ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
-                Surface.ROTATION_0, new Point(100, 100), new Rect() /* contentInsets */,
-                new Rect() /* letterboxInsets*/, false /* isLowResolution */,
-                true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN, 0 /* mSystemUiVisibility */,
-                false /* isTranslucent */, false /* hasImeSurface */, 0 /* uiMode */);
+    /**
+     * Verifies that activity snapshot is skipped if the persister queue has too many pending write
+     * items.
+     */
+    @Test
+    public void testSkipRecordActivity() {
+        doReturn(createSnapshot()).when(mActivitySnapshotController).recordSnapshotInner(any());
+        final Task task = createTask(mDisplayContent);
+
+        mSnapshotPersistQueue.setPaused(true);
+        final ArrayList<ActivityRecord> tmpList = new ArrayList<>();
+        for (int i = 0; i < MAX_STORE_QUEUE_DEPTH; ++i) {
+            tmpList.clear();
+            final ActivityRecord activity = createActivityRecord(task);
+            tmpList.add(activity);
+            mActivitySnapshotController.recordSnapshot(tmpList);
+            assertNotNull(mActivitySnapshotController.findSavedFile(activity));
+        }
+        tmpList.clear();
+        final ActivityRecord activity = createActivityRecord(task);
+        tmpList.add(activity);
+        mActivitySnapshotController.recordSnapshot(tmpList);
+        assertNull(mActivitySnapshotController.findSavedFile(activity));
     }
 }
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 e0b29c9..1cb1e3c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -511,6 +511,7 @@
     @Test
     public void testSupportsMultiWindow_nonResizable() {
         final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setComponent(getUniqueComponentName(mContext.getPackageName()))
                 .setCreateTask(true)
                 .setResizeMode(RESIZE_MODE_UNRESIZEABLE)
                 .build();
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 40da9ea..579ed66 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -365,8 +365,8 @@
         assertTrue(outPrevActivities.isEmpty());
         assertTrue(predictable);
         // reset
-        tf1.setAdjacentTaskFragment(null);
-        tf2.setAdjacentTaskFragment(null);
+        tf1.clearAdjacentTaskFragments();
+        tf2.clearAdjacentTaskFragments();
         tf1.setCompanionTaskFragment(null);
         tf2.setCompanionTaskFragment(null);
 
@@ -398,8 +398,8 @@
         assertTrue(predictable);
         // reset
         outPrevActivities.clear();
-        tf2.setAdjacentTaskFragment(null);
-        tf3.setAdjacentTaskFragment(null);
+        tf2.clearAdjacentTaskFragments();
+        tf3.clearAdjacentTaskFragments();
 
         final TaskFragment tf4 = createTaskFragmentWithActivity(task);
         // Stacked + next companion to top => predict for previous activity below companion.
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaGroupTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaGroupTest.java
index 87dbca5..060b379 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaGroupTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaGroupTest.java
@@ -84,6 +84,7 @@
 
     @Test
     public void testGetRequestedOrientationForDisplay() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final Task task = new TaskBuilder(mSupervisor)
                 .setTaskDisplayArea(mTaskDisplayArea).setCreateActivity(true).build();
         final ActivityRecord activity = task.getTopNonFinishingActivity();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
index 7b2cd63..0a7df5a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
@@ -491,6 +491,7 @@
     @Test
     public void testSetIgnoreOrientationRequest_callSuperOnDescendantOrientationChangedNoSensor() {
         final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final Task stack =
                 new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
         final ActivityRecord activity = stack.getTopNonFinishingActivity();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 9cbea2e..db71f2b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -898,6 +898,7 @@
     public void testOrientationDefinedByKeyguard() {
         final DisplayContent dc = mDisplayContent;
         dc.getDisplayPolicy().setAwake(true);
+        dc.setIgnoreOrientationRequest(false);
 
         // Create a window that requests landscape orientation. It will define device orientation
         // by default.
@@ -925,6 +926,7 @@
     @Test
     public void testOrientationForAspectRatio() {
         final DisplayContent dc = createNewDisplay();
+        dc.setIgnoreOrientationRequest(false);
 
         // When display content is created its configuration is not yet initialized, which could
         // cause unnecessary configuration propagation, so initialize it here.
@@ -1034,6 +1036,7 @@
     @Test
     public void testAllowsTopmostFullscreenOrientation() {
         final DisplayContent dc = createNewDisplay();
+        dc.setIgnoreOrientationRequest(false);
         assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, dc.getOrientation());
         dc.getDisplayRotation().setFixedToUserRotation(
                 IWindowManager.FIXED_TO_USER_ROTATION_DISABLED);
@@ -1112,6 +1115,7 @@
     @Test
     public void testOnDescendantOrientationRequestChanged() {
         final DisplayContent dc = createNewDisplay();
+        dc.setIgnoreOrientationRequest(false);
         dc.getDisplayRotation().setFixedToUserRotation(
                 IWindowManager.FIXED_TO_USER_ROTATION_DISABLED);
         dc.getDefaultTaskDisplayArea().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
@@ -1130,6 +1134,7 @@
     @Test
     public void testOnDescendantOrientationRequestChanged_FrozenToUserRotation() {
         final DisplayContent dc = createNewDisplay();
+        dc.setIgnoreOrientationRequest(false);
         dc.getDisplayRotation().setFixedToUserRotation(
                 IWindowManager.FIXED_TO_USER_ROTATION_ENABLED);
         dc.getDisplayRotation().setUserRotation(
@@ -1152,6 +1157,7 @@
     @Test
     public void testOrientationBehind() {
         assertNull(mDisplayContent.getLastOrientationSource());
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final ActivityRecord prev = new ActivityBuilder(mAtm).setCreateTask(true)
                 .setScreenOrientation(getRotatedOrientation(mDisplayContent)).build();
         prev.setVisibleRequested(false);
@@ -1172,6 +1178,7 @@
     @Test
     public void testFixedToUserRotationChanged() {
         final DisplayContent dc = createNewDisplay();
+        dc.setIgnoreOrientationRequest(false);
         dc.getDisplayRotation().setFixedToUserRotation(
                 IWindowManager.FIXED_TO_USER_ROTATION_ENABLED);
         dc.getDisplayRotation().setUserRotation(
@@ -1589,6 +1596,7 @@
             W_INPUT_METHOD, W_NOTIFICATION_SHADE })
     @Test
     public void testApplyTopFixedRotationTransform() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
         spyOn(displayPolicy);
         // Only non-movable (gesture) navigation bar will be animated by fixed rotation animation.
@@ -1742,6 +1750,7 @@
     @Test
     public void testFixedRotationWithPip() {
         final DisplayContent displayContent = mDefaultDisplay;
+        displayContent.setIgnoreOrientationRequest(false);
         unblockDisplayRotation(displayContent);
         // Unblock the condition in PinnedTaskController#continueOrientationChangeIfNeeded.
         doNothing().when(displayContent).prepareAppTransition(anyInt());
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java
index 6397334..6527af1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java
@@ -77,7 +77,7 @@
         when(mMockActivityRecord.findMainWindow()).thenReturn(mMockWindowState);
 
         doReturn(mMockActivityRecord).when(mDisplayContent).topRunningActivity();
-        when(mDisplayContent.getIgnoreOrientationRequest()).thenReturn(true);
+        mDisplayContent.setIgnoreOrientationRequest(true);
 
         mMockAppCompatConfiguration = mock(AppCompatConfiguration.class);
         when(mMockAppCompatConfiguration.isDisplayRotationImmersiveAppCompatPolicyEnabled())
@@ -195,7 +195,7 @@
 
     @Test
     public void testIsRotationLockEnforced_ignoreOrientationRequestDisabled_lockNotEnforced() {
-        when(mDisplayContent.getIgnoreOrientationRequest()).thenReturn(false);
+        mDisplayContent.setIgnoreOrientationRequest(false);
 
         assertIsRotationLockEnforcedReturnsFalseForAllRotations();
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
index 708d686..bd15bc4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
@@ -106,6 +106,8 @@
 
         // Display: 1920x1200 (landscape). First and second display are both 860x1200 (portrait).
         mDisplay = new DualDisplayContent.Builder(mAtm, 1920, 1200).build();
+        // The test verifies that the display area can affect display's getLastOrientation().
+        mDisplay.setIgnoreOrientationRequest(false);
         mFirstRoot = mDisplay.mFirstRoot;
         mSecondRoot = mDisplay.mSecondRoot;
         mFirstTda = mDisplay.getTaskDisplayArea(FEATURE_FIRST_TASK_CONTAINER);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java b/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java
index 7cb62c5..d965125 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java
@@ -132,6 +132,7 @@
 
     @Test
     public void testClosingAppDifferentTaskOrientation() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final ActivityRecord activity1 = createActivityRecord(mDisplayContent);
         activity1.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
 
@@ -146,6 +147,7 @@
 
     @Test
     public void testMoveTaskToBackDifferentTaskOrientation() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final ActivityRecord activity1 = createActivityRecord(mDisplayContent);
         activity1.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 7e8bd38..699ed02 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -41,6 +41,7 @@
 import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE;
 import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
 
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertEquals;
@@ -63,6 +64,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
 
 import android.app.ActivityOptions;
 import android.app.WindowConfiguration;
@@ -77,12 +79,14 @@
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
 import android.util.Pair;
 
 import androidx.test.filters.MediumTest;
 
 import com.android.internal.app.ResolverActivity;
+import com.android.window.flags.Flags;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -693,6 +697,7 @@
     @Test
     public void testAwakeFromSleepingWithAppConfiguration() {
         final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
+        display.setIgnoreOrientationRequest(false);
         final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
         activity.moveFocusableActivityToTop("test");
         assertTrue(activity.getRootTask().isFocusedRootTaskOnDisplay());
@@ -1331,6 +1336,38 @@
         assertEquals(taskDisplayArea.getTopRootTask(), taskDisplayArea.getRootHomeTask());
     }
 
+    @EnableFlags(Flags.FLAG_ENABLE_TOP_VISIBLE_ROOT_TASK_PER_USER_TRACKING)
+    @Test
+    public void testSwitchUser_withVisibleRootTasks_storesAllVisibleRootTasksForCurrentUser() {
+        // Set up root tasks
+        final Task rootTask1 = mRootWindowContainer.getDefaultTaskDisplayArea().createRootTask(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final Task rootTask2 = mRootWindowContainer.getDefaultTaskDisplayArea().createRootTask(
+                WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final Task rootTask3 = mRootWindowContainer.getDefaultTaskDisplayArea().createRootTask(
+                WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        doReturn(rootTask3).when(mRootWindowContainer).getTopDisplayFocusedRootTask();
+
+        // Set up user ids and visibility
+        rootTask1.mUserId = mRootWindowContainer.mCurrentUser;
+        rootTask2.mUserId = mRootWindowContainer.mCurrentUser;
+        rootTask3.mUserId = mRootWindowContainer.mCurrentUser;
+        rootTask1.mVisibleRequested = false;
+        rootTask2.mVisibleRequested = true;
+        rootTask3.mVisibleRequested = true;
+
+        // Switch to a different user
+        int currentUser = mRootWindowContainer.mCurrentUser;
+        int otherUser = currentUser + 1;
+        mRootWindowContainer.switchUser(otherUser, null);
+
+        // Verify that the previous user persists it's previous visible root tasks
+        assertArrayEquals(
+                new int[]{rootTask2.mTaskId, rootTask3.mTaskId},
+                mRootWindowContainer.mUserVisibleRootTasks.get(currentUser).toArray()
+        );
+    }
+
     @Test
     public void testLockAllProfileTasks() {
         final int profileUid = UserHandle.PER_USER_RANGE + UserHandle.MIN_SECONDARY_USER_ID;
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 bf96f0eb..201ff51 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -107,6 +107,8 @@
 import android.platform.test.annotations.Presubmit;
 import android.provider.DeviceConfig;
 import android.provider.DeviceConfig.Properties;
+import android.view.DisplayCutout;
+import android.view.DisplayInfo;
 import android.view.InsetsFrameProvider;
 import android.view.InsetsSource;
 import android.view.InsetsState;
@@ -210,6 +212,37 @@
         return setUpApp(builder.build(), appBuilder);
     }
 
+    private void setUpLargeScreenDisplayWithApp(int dw, int dh) {
+        final DisplayContent display = mDisplayContent;
+        final DisplayInfo displayInfo = display.getDisplayInfo();
+        displayInfo.logicalWidth = dw;
+        displayInfo.logicalHeight = dh;
+        // Prevent legacy sdk from being affected by INSETS_DECOUPLED_CONFIGURATION_ENFORCED.
+        display.mInitialDisplayCutout = displayInfo.displayCutout = DisplayCutout.NO_CUTOUT;
+        // Smallest screen width=747dp according to 1400/(300/160).
+        display.mBaseDisplayDensity = displayInfo.logicalDensityDpi =
+                TestDisplayContent.DEFAULT_LOGICAL_DISPLAY_DENSITY;
+        doNothing().when(display).updateDisplayInfo(any());
+        resizeDisplay(display, displayInfo.logicalWidth, displayInfo.logicalHeight);
+        assertTrue(display.isLargeScreen());
+        if (com.android.window.flags.Flags.universalResizableByDefault()) {
+            assertTrue("Large screen must ignore orientation request",
+                    display.getIgnoreOrientationRequest());
+        } else {
+            display.setIgnoreOrientationRequest(true);
+        }
+        setUpApp(display, null /* appBuilder */);
+        spyOn(display.getDisplayRotation());
+    }
+
+    private void setUpLandscapeLargeScreenDisplayWithApp() {
+        setUpLargeScreenDisplayWithApp(/* dw */ 2800, /* dh */ 1400);
+    }
+
+    private void setUpPortraitLargeScreenDisplayWithApp() {
+        setUpLargeScreenDisplayWithApp(/* dw */ 1400, /* dh */ 2800);
+    }
+
     @Test
     public void testHorizontalReachabilityEnabledForTranslucentActivities() {
         testReachabilityEnabledForTranslucentActivity(/* dw */ 2500,  /* dh */1000,
@@ -658,9 +691,7 @@
 
     @Test
     public void testIsLetterboxed_activityFromBubble_returnsFalse() {
-        setUpDisplaySizeWithApp(1000, 2500);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
-        spyOn(mActivity);
+        setUpPortraitLargeScreenDisplayWithApp();
         doReturn(true).when(mActivity).getLaunchedFromBubble();
         prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
 
@@ -1694,10 +1725,9 @@
     @Test
     public void testGetLetterboxInnerBounds_noScalingApplied() {
         // Set up a display in portrait and ignoring orientation request.
-        final int dw = 1400;
-        final int dh = 2800;
-        setUpDisplaySizeWithApp(dw, dh);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpPortraitLargeScreenDisplayWithApp();
+        final int dw = mDisplayContent.mBaseDisplayWidth;
+        final int dh = mDisplayContent.mBaseDisplayHeight;
 
         // Rotate display to landscape.
         rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
@@ -1823,8 +1853,7 @@
     @Test
     public void testDisplayIgnoreOrientationRequest_fixedOrientationAppLaunchedLetterbox() {
         // Set up a display in landscape and ignoring orientation request.
-        setUpDisplaySizeWithApp(2800, 1400);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
 
         // Portrait fixed app without max aspect.
         prepareUnresizable(mActivity, /* maxAspect= */ 0, SCREEN_ORIENTATION_PORTRAIT);
@@ -1852,8 +1881,7 @@
     @Test
     public void testDisplayIgnoreOrientationRequest_fixedOrientationAppRespectMinAspectRatio() {
         // Set up a display in landscape and ignoring orientation request.
-        setUpDisplaySizeWithApp(2800, 1400);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
 
         // Portrait fixed app with min aspect ratio higher that aspect ratio override for fixed
         // orientation letterbox.
@@ -1884,8 +1912,7 @@
     @Test
     public void testDisplayIgnoreOrientationRequest_fixedOrientationAppRespectMaxAspectRatio() {
         // Set up a display in landscape and ignoring orientation request.
-        setUpDisplaySizeWithApp(2800, 1400);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
 
         // Portrait fixed app with max aspect ratio lower that aspect ratio override for fixed
         // orientation letterbox.
@@ -1915,8 +1942,7 @@
     @Test
     public void testDisplayIgnoreOrientationRequest_fixedOrientationAppWithAspectRatioOverride() {
         // Set up a display in landscape and ignoring orientation request.
-        setUpDisplaySizeWithApp(2800, 1400);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
 
         final float fixedOrientationLetterboxAspectRatio = 1.1f;
         mActivity.mWmService.mAppCompatConfiguration.setFixedOrientationLetterboxAspectRatio(
@@ -2011,8 +2037,7 @@
     @Test
     public void testDisplayIgnoreOrientationRequest_unresizableWithCorrespondingMinAspectRatio() {
         // Set up a display in landscape and ignoring orientation request.
-        setUpDisplaySizeWithApp(2800, 1400);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
 
         final float fixedOrientationLetterboxAspectRatio = 1.1f;
         mActivity.mWmService.mAppCompatConfiguration.setFixedOrientationLetterboxAspectRatio(
@@ -2045,13 +2070,10 @@
     @Test
     public void testComputeConfigResourceOverrides_unresizableApp() {
         // Set up a display in landscape and ignoring orientation request.
-        setUpDisplaySizeWithApp(2800, 1400);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
 
         prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
 
-        final Rect activityBounds = new Rect(mActivity.getBounds());
-
         int originalScreenWidthDp = mActivity.getConfiguration().screenWidthDp;
         int originalScreenHeighthDp = mActivity.getConfiguration().screenHeightDp;
 
@@ -2068,7 +2090,7 @@
 
         // After we rotate, the activity should go in the size-compat mode and report the same
         // configuration values.
-        assertDownScaled();
+        assertThat(mActivity.inSizeCompatMode()).isTrue();
         assertEquals(originalScreenWidthDp, mActivity.getConfiguration().smallestScreenWidthDp);
         assertEquals(originalScreenWidthDp, mActivity.getConfiguration().screenWidthDp);
         assertEquals(originalScreenHeighthDp, mActivity.getConfiguration().screenHeightDp);
@@ -2087,14 +2109,11 @@
     @Test
     public void testComputeConfigResourceOverrides_resizableFixedOrientationActivity() {
         // Set up a display in landscape and ignoring orientation request.
-        setUpDisplaySizeWithApp(2800, 1400);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
 
         // Portrait fixed app without max aspect.
         prepareLimitedBounds(mActivity, SCREEN_ORIENTATION_PORTRAIT, false /* isUnresizable */);
 
-        final Rect activityBounds = new Rect(mActivity.getBounds());
-
         int originalScreenWidthDp = mActivity.getConfiguration().screenWidthDp;
         int originalScreenHeighthDp = mActivity.getConfiguration().screenHeightDp;
 
@@ -2206,10 +2225,10 @@
 
     @Test
     public void testSystemFullscreenOverrideForLandscapeDisplay() {
-        final int displayWidth = 1600;
-        final int displayHeight = 1400;
-        setUpDisplaySizeWithApp(displayWidth, displayHeight);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
+        final int displayWidth = mDisplayContent.mBaseDisplayWidth;
+        final int displayHeight = mDisplayContent.mBaseDisplayHeight;
+
         spyOn(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides());
         doReturn(true).when(
                 mActivity.mAppCompatController.getAppCompatAspectRatioOverrides())
@@ -2226,10 +2245,10 @@
 
     @Test
     public void testSystemFullscreenOverrideForPortraitDisplay() {
-        final int displayWidth = 1400;
-        final int displayHeight = 1600;
-        setUpDisplaySizeWithApp(displayWidth, displayHeight);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpPortraitLargeScreenDisplayWithApp();
+        final int displayWidth = mDisplayContent.mBaseDisplayWidth;
+        final int displayHeight = mDisplayContent.mBaseDisplayHeight;
+
         spyOn(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides());
         doReturn(true).when(
                 mActivity.mAppCompatController.getAppCompatAspectRatioOverrides())
@@ -2619,7 +2638,7 @@
     @EnableCompatChanges({ActivityInfo.OVERRIDE_RESPECT_REQUESTED_ORIENTATION})
     public void testOverrideRespectRequestedOrientationIsEnabled_orientationIsRespected() {
         // Set up a display in landscape
-        setUpDisplaySizeWithApp(2800, 1400);
+        setUpDisplaySizeWithApp(1000, 500);
 
         final ActivityRecord activity = buildActivityRecord(/* supportsSizeChanges= */ false,
                 RESIZE_MODE_UNRESIZEABLE, SCREEN_ORIENTATION_PORTRAIT);
@@ -2636,7 +2655,7 @@
     @EnableCompatChanges({ActivityInfo.OVERRIDE_RESPECT_REQUESTED_ORIENTATION})
     public void testOverrideRespectRequestedOrientationIsEnabled_multiWindow_orientationIgnored() {
         // Set up a display in landscape
-        setUpDisplaySizeWithApp(2800, 1400);
+        setUpDisplaySizeWithApp(1000, 500);
 
         final ActivityRecord activity = buildActivityRecord(/* supportsSizeChanges= */ false,
                 RESIZE_MODE_UNRESIZEABLE, SCREEN_ORIENTATION_PORTRAIT);
@@ -2655,10 +2674,9 @@
     @Test
     public void testSplitAspectRatioForUnresizableLandscapeApps() {
         // Set up a display in portrait and ignoring orientation request.
-        int screenWidth = 1400;
-        int screenHeight = 1600;
-        setUpDisplaySizeWithApp(screenWidth, screenHeight);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLargeScreenDisplayWithApp(1400, 2400);
+        final int screenWidth = mDisplayContent.mBaseDisplayWidth;
+        final int screenHeight = mDisplayContent.mBaseDisplayHeight;
         mActivity.mWmService.mAppCompatConfiguration
                 .setIsSplitScreenAspectRatioForUnresizableAppsEnabled(true);
 
@@ -2692,10 +2710,9 @@
     @Test
     public void testDisplayAspectRatioForResizablePortraitApps() {
         // Set up a display in portrait and ignoring orientation request.
-        int displayWidth = 1400;
-        int displayHeight = 1600;
-        setUpDisplaySizeWithApp(displayWidth, displayHeight);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLargeScreenDisplayWithApp(1400, 2400);
+        final int displayWidth = mDisplayContent.mBaseDisplayWidth;
+        final int displayHeight = mDisplayContent.mBaseDisplayHeight;
         mWm.mAppCompatConfiguration.setFixedOrientationLetterboxAspectRatio(2f);
 
         // Enable display aspect ratio to take precedence before
@@ -2728,10 +2745,9 @@
     @Test
     public void testDisplayAspectRatioForResizableLandscapeApps() {
         // Set up a display in landscape and ignoring orientation request.
-        int displayWidth = 1600;
-        int displayHeight = 1400;
-        setUpDisplaySizeWithApp(displayWidth, displayHeight);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
+        final int displayWidth = mDisplayContent.mBaseDisplayWidth;
+        final int displayHeight = mDisplayContent.mBaseDisplayHeight;
         mWm.mAppCompatConfiguration.setFixedOrientationLetterboxAspectRatio(2f);
 
         // Enable display aspect ratio to take precedence before
@@ -2764,10 +2780,9 @@
     @Test
     public void testDisplayAspectRatioForUnresizableLandscapeApps() {
         // Set up a display in portrait and ignoring orientation request.
-        int displayWidth = 1400;
-        int displayHeight = 1600;
-        setUpDisplaySizeWithApp(displayWidth, displayHeight);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpPortraitLargeScreenDisplayWithApp();
+        final int displayWidth = mDisplayContent.mBaseDisplayWidth;
+        final int displayHeight = mDisplayContent.mBaseDisplayHeight;
 
         mActivity.mWmService.mAppCompatConfiguration.setFixedOrientationLetterboxAspectRatio(1.1f);
         // Enable display aspect ratio to take precedence before
@@ -2791,10 +2806,9 @@
     @Test
     public void testDisplayAspectRatioForUnresizablePortraitApps() {
         // Set up a display in landscape and ignoring orientation request.
-        int displayWidth = 1600;
-        int displayHeight = 1400;
-        setUpDisplaySizeWithApp(displayWidth, displayHeight);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
+        final int displayWidth = mDisplayContent.mBaseDisplayWidth;
+        final int displayHeight = mDisplayContent.mBaseDisplayHeight;
 
         mActivity.mWmService.mAppCompatConfiguration.setFixedOrientationLetterboxAspectRatio(1.1f);
         // Enable display aspect ratio to take precedence before
@@ -2819,8 +2833,7 @@
     public void
             testDisplayIgnoreOrientationRequest_orientationLetterboxBecameSizeCompatAfterRotate() {
         // Set up a display in landscape and ignoring orientation request.
-        setUpDisplaySizeWithApp(2800, 1400);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
 
         // Portrait fixed app without max aspect.
         prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
@@ -2837,7 +2850,7 @@
         // App should be in size compat.
         assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
                 .isLetterboxedForFixedOrientationAndAspectRatio());
-        assertDownScaled();
+        assertThat(mActivity.inSizeCompatMode()).isTrue();
         assertEquals(activityBounds.width(), newActivityBounds.width());
         assertEquals(activityBounds.height(), newActivityBounds.height());
         assertActivityMaxBoundsSandboxed();
@@ -2846,8 +2859,7 @@
     @Test
     public void testDisplayIgnoreOrientationRequest_sizeCompatAfterRotate() {
         // Set up a display in portrait and ignoring orientation request.
-        setUpDisplaySizeWithApp(1400, 2800);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpPortraitLargeScreenDisplayWithApp();
 
         // Portrait fixed app without max aspect.
         prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
@@ -2882,9 +2894,8 @@
     @Test
     public void testDisplayIgnoreOrientationRequest_newLaunchedOrientationAppInLetterbox() {
         // Set up a display in landscape and ignoring orientation request.
-        setUpDisplaySizeWithApp(2800, 1400);
+        setUpLandscapeLargeScreenDisplayWithApp();
         final DisplayContent display = mActivity.mDisplayContent;
-        display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
 
         // Portrait fixed app without max aspect.
         prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
@@ -2928,9 +2939,7 @@
     @EnableCompatChanges({ActivityInfo.OVERRIDE_ENABLE_INSETS_DECOUPLED_CONFIGURATION})
     public void testDisplayIgnoreOrientationRequest_orientationChangedToUnspecified() {
         // Set up a display in landscape and ignoring orientation request.
-        setUpDisplaySizeWithApp(2800, 1400);
-        final DisplayContent display = mActivity.mDisplayContent;
-        display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
 
         // Portrait fixed app without max aspect.
         prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
@@ -2950,9 +2959,8 @@
     @Test
     public void testDisplayIgnoreOrientationRequest_newLaunchedMaxAspectApp() {
         // Set up a display in landscape and ignoring orientation request.
-        setUpDisplaySizeWithApp(2800, 1400);
+        setUpLandscapeLargeScreenDisplayWithApp();
         final DisplayContent display = mActivity.mDisplayContent;
-        display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
 
         // Portrait fixed app without max aspect.
         prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
@@ -3001,9 +3009,7 @@
     @SuppressWarnings("GuardedBy")
     public void testDisplayIgnoreOrientationRequest_pausedAppNotLostSizeCompat() {
         // Set up a display in landscape and ignoring orientation request.
-        setUpDisplaySizeWithApp(2800, 1400);
-        final DisplayContent display = mActivity.mDisplayContent;
-        display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
 
         // Portrait fixed app.
         prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
@@ -3019,7 +3025,6 @@
         // App should be in size compat.
         assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
                 .isLetterboxedForFixedOrientationAndAspectRatio());
-        assertDownScaled();
         assertThat(mActivity.inSizeCompatMode()).isTrue();
         // Activity max bounds are sandboxed due to size compat mode.
         assertActivityMaxBoundsSandboxed();
@@ -3035,7 +3040,7 @@
         verify(scmPolicy, never()).clearSizeCompatMode();
         assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
                 .isLetterboxedForFixedOrientationAndAspectRatio());
-        assertDownScaled();
+        assertThat(mActivity.inSizeCompatMode()).isTrue();
         assertEquals(activityBounds, mActivity.getBounds());
         // Activity max bounds are sandboxed due to size compat.
         assertActivityMaxBoundsSandboxed();
@@ -3044,9 +3049,8 @@
     @Test
     public void testDisplayIgnoreOrientationRequest_rotated180_notInSizeCompat() {
         // Set up a display in landscape and ignoring orientation request.
-        setUpDisplaySizeWithApp(2800, 1400);
+        setUpLandscapeLargeScreenDisplayWithApp();
         final DisplayContent display = mActivity.mDisplayContent;
-        display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
 
         // Portrait fixed app.
         prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
@@ -3063,7 +3067,7 @@
         // App should be in size compat.
         assertFalse(mActivity.mAppCompatController.getAppCompatAspectRatioPolicy()
                 .isLetterboxedForFixedOrientationAndAspectRatio());
-        assertDownScaled();
+        assertThat(mActivity.inSizeCompatMode()).isTrue();
         assertActivityMaxBoundsSandboxed();
 
         // Rotate display to landscape.
@@ -3246,8 +3250,9 @@
 
     @Test
     public void testTaskDisplayAreaNotFillDisplay() {
-        setUpDisplaySizeWithApp(1400, 2800);
+        setUpPortraitLargeScreenDisplayWithApp();
         final DisplayContent display = mActivity.mDisplayContent;
+        display.setIgnoreOrientationRequest(false);
         final TaskDisplayArea taskDisplayArea = mActivity.getDisplayArea();
         taskDisplayArea.setBounds(0, 0, 1000, 2400);
 
@@ -3430,8 +3435,7 @@
     @Test
     public void testIsHorizontalReachabilityEnabled_splitScreen_false() {
         mAtm.mDevEnableNonResizableMultiWindow = true;
-        setUpDisplaySizeWithApp(2800, 1000);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
         mWm.mAppCompatConfiguration.setIsHorizontalReachabilityEnabled(true);
         setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);
         final TestSplitOrganizer organizer =
@@ -3518,8 +3522,7 @@
 
     @Test
     public void testIsHorizontalReachabilityEnabled_emptyBounds_true() {
-        setUpDisplaySizeWithApp(/* dw */ 2800, /* dh */ 1000);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
         mWm.mAppCompatConfiguration.setIsHorizontalReachabilityEnabled(true);
         setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);
 
@@ -3566,8 +3569,7 @@
 
     @Test
     public void testIsHorizontalReachabilityEnabled_doesNotMatchParentHeight_false() {
-        setUpDisplaySizeWithApp(2800, 1000);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
         mWm.mAppCompatConfiguration.setIsHorizontalReachabilityEnabled(true);
         setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);
 
@@ -3787,12 +3789,10 @@
     }
 
     private void assertLandscapeActivityAlignedToBottomWithNavbar(boolean immersive) {
-        final int screenHeight = 2800;
-        final int screenWidth = 1400;
+        setUpPortraitLargeScreenDisplayWithApp();
+        final int screenHeight = mDisplayContent.mBaseDisplayHeight;
+        final int screenWidth = mDisplayContent.mBaseDisplayWidth;
         final int taskbarHeight = 200;
-        setUpDisplaySizeWithApp(screenWidth, screenHeight);
-
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true);
         mActivity.mWmService.mAppCompatConfiguration.setLetterboxVerticalPositionMultiplier(1.0f);
 
         final InsetsSource navSource = new InsetsSource(
@@ -3972,8 +3972,7 @@
             float letterboxHorizontalPositionMultiplier, Rect fixedOrientationLetterbox,
             Rect sizeCompatUnscaled, Rect sizeCompatScaled) {
         // Set up a display in landscape and ignoring orientation request.
-        setUpDisplaySizeWithApp(2800, 1400);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
 
         mActivity.mWmService.mAppCompatConfiguration.setLetterboxHorizontalPositionMultiplier(
                 letterboxHorizontalPositionMultiplier);
@@ -4177,13 +4176,28 @@
 
     @Test
     public void testUpdateResolvedBoundsHorizontalPosition_activityFillParentWidth() {
+        // Set up a display in landscape and ignoring orientation request.
+        setUpLandscapeLargeScreenDisplayWithApp();
+        prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
+
+        final Consumer<Float> assertHorizontalPosition = letterboxHorizontalPositionMultiplier -> {
+            mActivity.mWmService.mAppCompatConfiguration.setLetterboxHorizontalPositionMultiplier(
+                    letterboxHorizontalPositionMultiplier);
+            mActivity.recomputeConfiguration();
+            assertFitted();
+            // Rotate to put activity in size compat mode.
+            rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
+            assertTrue(mActivity.inSizeCompatMode());
+            // Activity is in size compat mode but not scaled.
+            assertEquals(new Rect(0, 0, 1400, 700), mActivity.getBounds());
+            if (letterboxHorizontalPositionMultiplier < 1f) {
+                rotateDisplay(mActivity.mDisplayContent, ROTATION_0);
+            }
+        };
         // When activity width equals parent width, multiplier shouldn't have any effect.
-        assertHorizontalPositionForDifferentDisplayConfigsForLandscapeActivity(
-                /* letterboxHorizontalPositionMultiplier */ 0.0f);
-        assertHorizontalPositionForDifferentDisplayConfigsForLandscapeActivity(
-                /* letterboxHorizontalPositionMultiplier */ 0.5f);
-        assertHorizontalPositionForDifferentDisplayConfigsForLandscapeActivity(
-                /* letterboxHorizontalPositionMultiplier */ 1.0f);
+        assertHorizontalPosition.accept(0.0f);
+        assertHorizontalPosition.accept(0.5f);
+        assertHorizontalPosition.accept(1.0f);
     }
 
     @Test
@@ -4354,8 +4368,7 @@
     @Test
     public void testUpdateResolvedBoundsHorizontalPosition_bookModeEnabled() {
         // Set up a display in landscape with a fixed-orientation PORTRAIT app
-        setUpDisplaySizeWithApp(2800, 1400);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
         mWm.mAppCompatConfiguration.setIsAutomaticReachabilityInBookModeEnabled(true);
         mWm.mAppCompatConfiguration.setLetterboxHorizontalPositionMultiplier(
                 1.0f /*letterboxHorizontalPositionMultiplier*/);
@@ -4380,8 +4393,7 @@
     @Test
     public void testUpdateResolvedBoundsHorizontalPosition_bookModeDisabled_centered() {
         // Set up a display in landscape with a fixed-orientation PORTRAIT app
-        setUpDisplaySizeWithApp(2800, 1400);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpLandscapeLargeScreenDisplayWithApp();
         mWm.mAppCompatConfiguration.setIsAutomaticReachabilityInBookModeEnabled(false);
         mWm.mAppCompatConfiguration.setLetterboxHorizontalPositionMultiplier(0.5f);
         prepareUnresizable(mActivity, 1.75f, SCREEN_ORIENTATION_PORTRAIT);
@@ -4462,8 +4474,7 @@
             float letterboxVerticalPositionMultiplier, Rect fixedOrientationLetterbox,
             Rect sizeCompatUnscaled, Rect sizeCompatScaled) {
         // Set up a display in portrait and ignoring orientation request.
-        setUpDisplaySizeWithApp(1400, 2800);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        setUpPortraitLargeScreenDisplayWithApp();
 
         mActivity.mWmService.mAppCompatConfiguration.setLetterboxVerticalPositionMultiplier(
                 letterboxVerticalPositionMultiplier);
@@ -5036,23 +5047,6 @@
         return (dimensionToSplit - (dividerWindowWidth - dividerInsets * 2)) / 2;
     }
 
-    private void assertHorizontalPositionForDifferentDisplayConfigsForLandscapeActivity(
-            float letterboxHorizontalPositionMultiplier) {
-        // Set up a display in landscape and ignoring orientation request.
-        setUpDisplaySizeWithApp(2800, 1400);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
-
-        mActivity.mWmService.mAppCompatConfiguration.setLetterboxHorizontalPositionMultiplier(
-                letterboxHorizontalPositionMultiplier);
-        prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
-        assertFitted();
-        // Rotate to put activity in size compat mode.
-        rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
-        assertTrue(mActivity.inSizeCompatMode());
-        // Activity is in size compat mode but not scaled.
-        assertEquals(new Rect(0, 0, 1400, 700), mActivity.getBounds());
-    }
-
     private void assertVerticalPositionForDifferentDisplayConfigsForPortraitActivity(
             float letterboxVerticalPositionMultiplier) {
         // Set up a display in portrait and ignoring orientation request.
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index 08622e6..921228f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -78,6 +78,8 @@
 
 import com.android.dx.mockito.inline.extended.StaticMockitoSession;
 import com.android.internal.os.BackgroundThread;
+import com.android.internal.protolog.ProtoLog;
+import com.android.internal.protolog.WmProtoLogGroups;
 import com.android.server.AnimationThread;
 import com.android.server.DisplayThread;
 import com.android.server.LocalServices;
@@ -183,6 +185,8 @@
     }
 
     private void setUp() {
+        ProtoLog.init(WmProtoLogGroups.values());
+
         if (mOnBeforeServicesCreated != null) {
             mOnBeforeServicesCreated.run();
         }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index 65a6a69..dafa96f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -51,6 +51,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.clearInvocations;
@@ -62,6 +63,7 @@
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.os.Binder;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
 import android.view.SurfaceControl;
 import android.view.View;
@@ -1066,6 +1068,98 @@
                 Math.min(outConfig.screenWidthDp, outConfig.screenHeightDp));
     }
 
+    @EnableFlags(Flags.FLAG_ALLOW_MULTIPLE_ADJACENT_TASK_FRAGMENTS)
+    @Test
+    public void testSetAdjacentTaskFragments() {
+        final Task task = createTask(mDisplayContent);
+        final TaskFragment tf0 = createTaskFragmentWithActivity(task);
+        final TaskFragment tf1 = createTaskFragmentWithActivity(task);
+        final TaskFragment tf2 = createTaskFragmentWithActivity(task);
+        final TaskFragment.AdjacentSet adjacentTfs = new TaskFragment.AdjacentSet(tf0, tf1, tf2);
+        assertFalse(tf0.hasAdjacentTaskFragment());
+
+        tf0.setAdjacentTaskFragments(adjacentTfs);
+
+        assertSame(adjacentTfs, tf0.getAdjacentTaskFragments());
+        assertSame(adjacentTfs, tf1.getAdjacentTaskFragments());
+        assertSame(adjacentTfs, tf2.getAdjacentTaskFragments());
+        assertTrue(tf0.hasAdjacentTaskFragment());
+        assertTrue(tf1.hasAdjacentTaskFragment());
+        assertTrue(tf2.hasAdjacentTaskFragment());
+
+        final TaskFragment.AdjacentSet adjacentTfs2 = new TaskFragment.AdjacentSet(tf0, tf1);
+        tf0.setAdjacentTaskFragments(adjacentTfs2);
+
+        assertSame(adjacentTfs2, tf0.getAdjacentTaskFragments());
+        assertSame(adjacentTfs2, tf1.getAdjacentTaskFragments());
+        assertNull(tf2.getAdjacentTaskFragments());
+        assertTrue(tf0.hasAdjacentTaskFragment());
+        assertTrue(tf1.hasAdjacentTaskFragment());
+        assertFalse(tf2.hasAdjacentTaskFragment());
+    }
+
+    @EnableFlags(Flags.FLAG_ALLOW_MULTIPLE_ADJACENT_TASK_FRAGMENTS)
+    @Test
+    public void testClearAdjacentTaskFragments() {
+        final Task task = createTask(mDisplayContent);
+        final TaskFragment tf0 = createTaskFragmentWithActivity(task);
+        final TaskFragment tf1 = createTaskFragmentWithActivity(task);
+        final TaskFragment tf2 = createTaskFragmentWithActivity(task);
+        final TaskFragment.AdjacentSet adjacentTfs = new TaskFragment.AdjacentSet(tf0, tf1, tf2);
+        tf0.setAdjacentTaskFragments(adjacentTfs);
+
+        tf0.clearAdjacentTaskFragments();
+
+        assertNull(tf0.getAdjacentTaskFragments());
+        assertNull(tf1.getAdjacentTaskFragments());
+        assertNull(tf2.getAdjacentTaskFragments());
+        assertFalse(tf0.hasAdjacentTaskFragment());
+        assertFalse(tf1.hasAdjacentTaskFragment());
+        assertFalse(tf2.hasAdjacentTaskFragment());
+    }
+
+    @EnableFlags(Flags.FLAG_ALLOW_MULTIPLE_ADJACENT_TASK_FRAGMENTS)
+    @Test
+    public void testRemoveFromAdjacentTaskFragments() {
+        final Task task = createTask(mDisplayContent);
+        final TaskFragment tf0 = createTaskFragmentWithActivity(task);
+        final TaskFragment tf1 = createTaskFragmentWithActivity(task);
+        final TaskFragment tf2 = createTaskFragmentWithActivity(task);
+        final TaskFragment.AdjacentSet adjacentTfs = new TaskFragment.AdjacentSet(tf0, tf1, tf2);
+        tf0.setAdjacentTaskFragments(adjacentTfs);
+
+        tf0.removeFromAdjacentTaskFragments();
+
+        assertNull(tf0.getAdjacentTaskFragments());
+        assertSame(adjacentTfs, tf1.getAdjacentTaskFragments());
+        assertSame(adjacentTfs, tf2.getAdjacentTaskFragments());
+        assertFalse(adjacentTfs.contains(tf0));
+        assertTrue(tf1.isAdjacentTo(tf2));
+        assertTrue(tf2.isAdjacentTo(tf1));
+        assertFalse(tf1.isAdjacentTo(tf0));
+        assertFalse(tf0.isAdjacentTo(tf1));
+        assertFalse(tf0.isAdjacentTo(tf0));
+        assertFalse(tf1.isAdjacentTo(tf1));
+    }
+
+    @EnableFlags(Flags.FLAG_ALLOW_MULTIPLE_ADJACENT_TASK_FRAGMENTS)
+    @Test
+    public void testRemoveFromAdjacentTaskFragmentsWhenRemove() {
+        final Task task = createTask(mDisplayContent);
+        final TaskFragment tf0 = createTaskFragmentWithActivity(task);
+        final TaskFragment tf1 = createTaskFragmentWithActivity(task);
+        final TaskFragment tf2 = createTaskFragmentWithActivity(task);
+        final TaskFragment.AdjacentSet adjacentTfs = new TaskFragment.AdjacentSet(tf0, tf1, tf2);
+        tf0.setAdjacentTaskFragments(adjacentTfs);
+
+        tf0.removeImmediately();
+
+        assertNull(tf0.getAdjacentTaskFragments());
+        assertSame(adjacentTfs, tf1.getAdjacentTaskFragments());
+        assertSame(adjacentTfs, tf2.getAdjacentTaskFragments());
+        assertFalse(adjacentTfs.contains(tf0));
+    }
+
     private WindowState createAppWindow(ActivityRecord app, String name) {
         final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, app, name,
                 0 /* ownerId */, false /* ownerCanAddInternalSystemWindow */, new TestIWindow());
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java
index 29f48b8..f145b40 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java
@@ -65,33 +65,27 @@
     public void testAppRemoved() {
         final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
         mCache.putSnapshot(window.getTask(), createSnapshot());
-        assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */,
-                false /* restoreFromDisk */, false /* isLowResolution */));
+        assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */));
         mCache.onAppRemoved(window.mActivityRecord);
-        assertNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */,
-                false /* restoreFromDisk */, false /* isLowResolution */));
+        assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */));
     }
 
     @Test
     public void testAppDied() {
         final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
         mCache.putSnapshot(window.getTask(), createSnapshot());
-        assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */,
-                false /* restoreFromDisk */, false /* isLowResolution */));
+        assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */));
         mCache.onAppDied(window.mActivityRecord);
-        assertNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */,
-                false /* restoreFromDisk */, false /* isLowResolution */));
+        assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */));
     }
 
     @Test
     public void testTaskRemoved() {
         final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
         mCache.putSnapshot(window.getTask(), createSnapshot());
-        assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */,
-                false /* restoreFromDisk */, false /* isLowResolution */));
+        assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */));
         mCache.onIdRemoved(window.getTask().mTaskId);
-        assertNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */,
-                false /* restoreFromDisk */, false /* isLowResolution */));
+        assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */));
     }
 
     @Test
@@ -99,16 +93,14 @@
         final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
         mPersister.persistSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, createSnapshot());
         mSnapshotPersistQueue.waitForQueueEmpty();
-        assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId,
-                false /* restoreFromDisk */, false /* isLowResolution */));
+        assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */));
 
         // Load it from disk
-        assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId,
-                true /* restoreFromDisk */, true /* isLowResolution */));
+        assertNotNull(mCache.getSnapshotFromDisk(window.getTask().mTaskId, mWm.mCurrentUserId,
+                true /* isLowResolution */, TaskSnapshot.REFERENCE_NONE));
 
         // Make sure it's not in the cache now.
-        assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId,
-                false /* restoreFromDisk */, false /* isLowResolution */));
+        assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */));
     }
 
     @Test
@@ -116,20 +108,20 @@
         final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
         mPersister.persistSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, createSnapshot());
         mSnapshotPersistQueue.waitForQueueEmpty();
-        assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId,
-                false /* restoreFromDisk */, false /* isLowResolution */));
+        assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */));
 
         // Load it from disk
-        assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId,
-                true /* restoreFromDisk */, false /* isLowResolution */));
+        assertNotNull(mCache.getSnapshotFromDisk(window.getTask().mTaskId, mWm.mCurrentUserId,
+                false/* isLowResolution */, TaskSnapshot.REFERENCE_NONE));
     }
 
     @Test
     public void testClearCache() {
         final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
         mCache.putSnapshot(window.getTask(), mSnapshot);
-        assertEquals(mSnapshot, mCache.getSnapshot(window.getTask().mTaskId, 0, false, false));
+        assertEquals(mSnapshot, mCache.getSnapshot(window.getTask().mTaskId,
+                false /* isLowResolution */));
         mCache.clearRunningCache();
-        assertNull(mCache.getSnapshot(window.getTask().mTaskId, 0, false, false));
+        assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */));
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotLowResDisabledTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotLowResDisabledTest.java
index 7432537..9bde066 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotLowResDisabledTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotLowResDisabledTest.java
@@ -129,23 +129,20 @@
         final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
         mPersister.persistSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, createSnapshot());
         mSnapshotPersistQueue.waitForQueueEmpty();
-        assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId,
-                false /* restoreFromDisk */, false /* isLowResolution */));
+        assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */));
 
         // Attempt to load the low-res snapshot from the disk
-        assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId,
-                true /* restoreFromDisk */, true /* isLowResolution */));
+        assertNull(mCache.getSnapshotFromDisk(window.getTask().mTaskId, mWm.mCurrentUserId,
+                true/* isLowResolution */, TaskSnapshot.REFERENCE_NONE));
 
         // Load the high-res (default) snapshot from disk
-        assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId,
-                true /* restoreFromDisk */, false /* isLowResolution */));
+        assertNotNull(mCache.getSnapshotFromDisk(window.getTask().mTaskId, mWm.mCurrentUserId,
+                false /* isLowResolution */, TaskSnapshot.REFERENCE_NONE));
 
         // Make sure it's not in the cache now.
-        assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId,
-                false /* restoreFromDisk */, true /* isLowResolution */));
+        assertNull(mCache.getSnapshot(window.getTask().mTaskId, true /* isLowResolution */));
 
         // Make sure it's not in the cache now.
-        assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId,
-                false /* restoreFromDisk */, false /* isLowResolution */));
+        assertNull(mCache.getSnapshot(window.getTask().mTaskId, false /* isLowResolution */));
     }
 }
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 e4512c3..1febc9f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -527,6 +527,7 @@
 
     @Test
     public void testHandlesOrientationChangeFromDescendant() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final Task rootTask = createTask(mDisplayContent,
                 WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
         final Task leafTask1 = createTaskInRootTask(rootTask, 0 /* userId */);
@@ -1570,6 +1571,7 @@
 
     @Test
     public void testNotSpecifyOrientationByFloatingTask() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final Task task = new TaskBuilder(mSupervisor)
                 .setCreateActivity(true).setCreateParentTask(true).build();
         final ActivityRecord activity = task.getTopMostActivity();
@@ -1589,6 +1591,7 @@
 
     @Test
     public void testNotSpecifyOrientation_taskDisplayAreaNotFocused() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
         final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
                 mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
@@ -1625,6 +1628,7 @@
 
     @Test
     public void testTaskOrientationOnDisplayWindowingModeChange() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         // Skip unnecessary operations to speed up the test.
         mAtm.deferWindowLayout();
         final Task task = getTestTask();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
index 039a3dd..78f32c1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -1333,6 +1333,7 @@
 
     @Test
     public void testDeferRotationForTransientLaunch() {
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final TestTransitionPlayer player = registerTestTransitionPlayer();
         assumeFalse(mDisplayContent.mTransitionController.useShellTransitionsRotation());
         final ActivityRecord app = new ActivityBuilder(mAtm).setCreateTask(true).build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransparentPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/TransparentPolicyTest.java
index 42752c3..f1180ff 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransparentPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransparentPolicyTest.java
@@ -314,6 +314,7 @@
         runTestScenario((robot) -> {
             robot.transparentActivity((ta) -> {
                 ta.applyOnActivity((a) -> {
+                    a.setIgnoreOrientationRequest(false);
                     a.applyToTopActivity((topActivity) -> {
                         topActivity.mWmService.mAppCompatConfiguration
                                 .setLetterboxHorizontalPositionMultiplier(1.0f);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
index d183cf7..f3a2e86 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
@@ -46,6 +46,7 @@
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Bundle;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
 import android.view.Display;
 import android.view.DisplayInfo;
@@ -54,7 +55,12 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.window.flags.Flags;
+
+import com.google.common.truth.Expect;
+
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -65,6 +71,7 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
+
 /**
  * Build/Install/Run:
  *  atest WmTests:WindowContextListenerControllerTests
@@ -86,6 +93,9 @@
     private WindowProcessController mWpc;
     private WindowContainer<?> mContainer;
 
+    @Rule
+    public final Expect mExpect = Expect.create();
+
     @Before
     public void setUp() {
         initMocks(this);
@@ -341,6 +351,30 @@
         assertThat(clientToken.mDisplayId).isEqualTo(mDisplayContent.mDisplayId);
     }
 
+    @Test
+    @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+    public void assertCallerCanReparentListener_returnsTrueWhenExpected() {
+        mController.registerWindowContainerListener(mWpc, mClientToken, mContainer,
+                TYPE_APPLICATION_OVERLAY, null /*  options */);
+
+        // Here there are several checks in one test as wm tests are expensive.
+
+        // Correct conditions -> returns true
+        mExpect.that(mController.assertCallerCanReparentListener(mClientToken,
+                /* callerCanManageAppTokens= */ true,
+                /* callingUid= */ mWpc.mUid,
+                /* displayId= */ DEFAULT_DISPLAY + 1
+        )).isTrue();
+
+        // sameDisplayId (so, container already attached) -> returnsFalse
+        mExpect.that(mController.assertCallerCanReparentListener(
+                mClientToken,
+                /* callerCanManageAppTokens= */ true,
+                /* callingUid= */ mWpc.mUid,
+                /* displayId= */ DEFAULT_DISPLAY // <- same display ID
+        )).isFalse();
+    }
+
     private static class TestWindowTokenClient extends WindowTokenClient {
         private Configuration mConfiguration;
         private int mDisplayId;
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 bfa6cb8..69df66e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -39,6 +39,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 import static android.view.flags.Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION;
 import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
@@ -70,6 +71,7 @@
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.description;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -86,10 +88,10 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 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.util.ArraySet;
 import android.util.MergedConfiguration;
 import android.view.ContentRecordingSession;
@@ -151,9 +153,6 @@
     @Rule
     public Expect mExpect = Expect.create();
 
-    @Rule
-    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
     @After
     public void tearDown() {
         mWm.mSensitiveContentPackages.clearBlockedApps();
@@ -1412,6 +1411,84 @@
         assertThat(result).isEqualTo(WindowManagerGlobal.ADD_INVALID_DISPLAY);
     }
 
+    /** Mocks some deps to associate a display content to a specific display id. */
+    private void setupReparentWindowContextToDisplayAreaTest(WindowToken windowToken,
+            DisplayContent dc, int displayId) {
+        spyOn(mWm.mWindowContextListenerController);
+        doReturn(dc).when(mWm.mRoot).getDisplayContentOrCreate(displayId);
+        doReturn(true).when(mWm.mWindowContextListenerController).assertCallerCanReparentListener(
+                any(), anyBoolean(), anyInt(), eq(displayId));
+        doReturn(windowToken).when(mWm.mWindowContextListenerController).getContainer(
+                eq(windowToken.token));
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+    public void reparentWindowContextToDisplayArea_newDisplay_reparented() {
+        final WindowToken windowToken = createTestClientWindowToken(TYPE_NOTIFICATION_SHADE,
+                mDisplayContent);
+        final int newDisplayId = 1;
+        final DisplayContent dc = createNewDisplay();
+        setupReparentWindowContextToDisplayAreaTest(windowToken, dc, newDisplayId);
+
+        assertThat(windowToken.getDisplayContent()).isEqualTo(mDisplayContent);
+
+        assertThat(mWm.reparentWindowContextToDisplayArea(mAppThread, windowToken.token,
+                newDisplayId)).isTrue();
+
+        assertThat(windowToken.getDisplayContent()).isNotEqualTo(mDisplayContent);
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+    public void reparentWindowContextToDisplayArea_newDisplayButFlagDisabled_notReparented() {
+        final WindowToken windowToken = createTestClientWindowToken(TYPE_NOTIFICATION_SHADE,
+                mDisplayContent);
+        final int newDisplayId = 1;
+        final DisplayContent dc = createNewDisplay();
+        setupReparentWindowContextToDisplayAreaTest(windowToken, dc, newDisplayId);
+
+        assertThat(mWm.reparentWindowContextToDisplayArea(mAppThread, windowToken.token,
+                newDisplayId)).isFalse();
+
+        assertThat(windowToken.getDisplayContent()).isEqualTo(mDisplayContent);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+    public void reparentWindowContext_afterReparent_DCNeedsLayout() {
+        final WindowToken windowToken = createTestClientWindowToken(TYPE_NOTIFICATION_SHADE,
+                mDisplayContent);
+        final int newDisplayId = 1;
+        final DisplayContent dc = createNewDisplay();
+        setupReparentWindowContextToDisplayAreaTest(windowToken, dc, newDisplayId);
+
+        assertThat(mWm.reparentWindowContextToDisplayArea(mAppThread, windowToken.token,
+                newDisplayId)).isTrue();
+
+        assertThat(dc.isLayoutNeeded()).isTrue();
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+    public void reparentWindowContext_afterReparent_traversalScheduled() {
+        final WindowToken windowToken = createTestClientWindowToken(TYPE_NOTIFICATION_SHADE,
+                mDisplayContent);
+        final int newDisplayId = 1;
+        final DisplayContent dc = createNewDisplay();
+        setupReparentWindowContextToDisplayAreaTest(windowToken, dc, newDisplayId);
+        spyOn(mWm.mWindowPlacerLocked);
+        reset(mWm.mWindowPlacerLocked);
+
+        verify(mWm.mWindowPlacerLocked, never()).requestTraversal();
+
+        assertThat(mWm.reparentWindowContextToDisplayArea(mAppThread, windowToken.token,
+                newDisplayId)).isTrue();
+
+        verify(mWm.mWindowPlacerLocked).requestTraversal();
+    }
+
+
     class TestResultReceiver implements IResultReceiver {
         public android.os.Bundle resultData;
         private final IBinder mBinder = mock(IBinder.class);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 410fa28..da4c522 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -777,6 +777,7 @@
     @Test
     public void testSetIgnoreOrientationRequest_taskDisplayArea() {
         removeGlobalMinSizeRestriction();
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
         final Task rootTask = taskDisplayArea.createRootTask(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
@@ -815,6 +816,7 @@
     @Test
     public void testSetIgnoreOrientationRequest_displayContent() {
         removeGlobalMinSizeRestriction();
+        mDisplayContent.setIgnoreOrientationRequest(false);
         final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
         final Task rootTask = taskDisplayArea.createRootTask(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
@@ -924,6 +926,49 @@
         assertEquals(dc.getDefaultTaskDisplayArea().mLaunchAdjacentFlagRootTask, null);
     }
 
+    @EnableFlags(Flags.FLAG_ALLOW_MULTIPLE_ADJACENT_TASK_FRAGMENTS)
+    @Test
+    public void testSetAdjacentLaunchRootSet() {
+        final DisplayContent dc = mWm.mRoot.getDisplayContent(Display.DEFAULT_DISPLAY);
+
+        final Task task1 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
+                dc, WINDOWING_MODE_MULTI_WINDOW, null);
+        final RunningTaskInfo info1 = task1.getTaskInfo();
+        final Task task2 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
+                dc, WINDOWING_MODE_MULTI_WINDOW, null);
+        final RunningTaskInfo info2 = task2.getTaskInfo();
+        final Task task3 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
+                dc, WINDOWING_MODE_MULTI_WINDOW, null);
+        final RunningTaskInfo info3 = task3.getTaskInfo();
+
+        WindowContainerTransaction wct = new WindowContainerTransaction();
+        wct.setAdjacentRootSet(info1.token, info2.token, info3.token);
+        mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
+        assertTrue(task1.hasAdjacentTaskFragment());
+        assertTrue(task2.hasAdjacentTaskFragment());
+        assertTrue(task3.hasAdjacentTaskFragment());
+        assertTrue(task1.isAdjacentTo(task2));
+        assertTrue(task1.isAdjacentTo(task3));
+        assertTrue(task2.isAdjacentTo(task3));
+
+        wct = new WindowContainerTransaction();
+        wct.clearAdjacentRoots(info1.token);
+        mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
+        assertFalse(task1.hasAdjacentTaskFragment());
+        assertTrue(task2.hasAdjacentTaskFragment());
+        assertTrue(task3.hasAdjacentTaskFragment());
+        assertFalse(task1.isAdjacentTo(task2));
+        assertFalse(task1.isAdjacentTo(task3));
+        assertTrue(task2.isAdjacentTo(task3));
+
+        wct = new WindowContainerTransaction();
+        wct.clearAdjacentRoots(info2.token);
+        mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
+        assertFalse(task2.hasAdjacentTaskFragment());
+        assertFalse(task3.hasAdjacentTaskFragment());
+        assertFalse(task2.isAdjacentTo(task3));
+    }
+
     @Test
     public void testTileAddRemoveChild() {
         final StubOrganizer listener = new StubOrganizer();
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 78e6cbf..b27025c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -201,14 +201,10 @@
      * {@link WindowTestsBase#setUpBase()}.
      */
     private static boolean sGlobalOverridesChecked;
+
     /**
      * Whether device-specific overrides have already been checked in
-     * {@link WindowTestsBase#setUpBase()} when the default display is used.
-     */
-    private static boolean sOverridesCheckedDefaultDisplay;
-    /**
-     * Whether device-specific overrides have already been checked in
-     * {@link WindowTestsBase#setUpBase()} when a {@link TestDisplayContent} is used.
+     * {@link WindowTestsBase#setUpBase()}.
      */
     private static boolean sOverridesCheckedTestDisplay;
 
@@ -332,17 +328,14 @@
     private void checkDeviceSpecificOverridesNotApplied() {
         // Check global overrides
         if (!sGlobalOverridesChecked) {
+            sGlobalOverridesChecked = true;
             assertEquals(0, mWm.mAppCompatConfiguration.getFixedOrientationLetterboxAspectRatio(),
                     0 /* delta */);
-            sGlobalOverridesChecked = true;
         }
         // Check display-specific overrides
-        if (!sOverridesCheckedDefaultDisplay && mDisplayContent == mDefaultDisplay) {
-            assertFalse(mDisplayContent.getIgnoreOrientationRequest());
-            sOverridesCheckedDefaultDisplay = true;
-        } else if (!sOverridesCheckedTestDisplay && mDisplayContent instanceof TestDisplayContent) {
-            assertFalse(mDisplayContent.getIgnoreOrientationRequest());
+        if (!sOverridesCheckedTestDisplay) {
             sOverridesCheckedTestDisplay = true;
+            assertFalse(mDisplayContent.mHasSetIgnoreOrientationRequest);
         }
     }
 
@@ -1121,7 +1114,7 @@
         displayContent.getDisplayRotation().configure(width, height);
         final Configuration c = new Configuration();
         displayContent.computeScreenConfiguration(c);
-        displayContent.onRequestedOverrideConfigurationChanged(c);
+        displayContent.performDisplayOverrideConfigUpdate(c);
     }
 
     static void makeDisplayLargeScreen(DisplayContent displayContent) {
@@ -2039,9 +2032,22 @@
         return new TestWindowToken(type, dc, persistOnEmpty);
     }
 
+    static TestWindowToken createTestClientWindowToken(int type, DisplayContent dc) {
+        SystemServicesTestRule.checkHoldsLock(dc.mWmService.mGlobalLock);
+
+        return new TestWindowToken(type, dc, false /* persistOnEmpty */, true /* fromClient */);
+    }
+
     /** Used so we can gain access to some protected members of the {@link WindowToken} class */
     static class TestWindowToken extends WindowToken {
 
+        private TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty,
+                boolean fromClient) {
+            super(dc.mWmService, mock(IBinder.class), type, persistOnEmpty, dc,
+                    false /* ownerCanManageAppTokens */, false /* roundedCornerOverlay */,
+                    fromClient /* fromClientToken */, null /* options */);
+        }
+
         private TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) {
             super(dc.mWmService, mock(IBinder.class), type, persistOnEmpty, dc,
                     false /* ownerCanManageAppTokens */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
index 35328a0e..f226b9d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
@@ -33,21 +33,27 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.content.res.Configuration;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
 import android.view.WindowInsets;
 import android.window.WindowContext;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.window.flags.Flags;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mockito;
 
 import java.util.function.BiFunction;
 
@@ -304,14 +310,39 @@
         // immediately. verify the window will hide without applying exit animation.
         mWm.removeWindowToken(win.mToken.token, false /* removeWindows */, false /* animateExit */,
                 mDisplayContent.mDisplayId);
-        verify(win).onSetAppExiting(Mockito.eq(false) /* animateExit */);
+        verify(win).onSetAppExiting(eq(false) /* animateExit */);
         verify(win).hide(false /* doAnimation */, false /* requestAnim */);
         assertFalse(win.isOnScreen());
-        verify(win.mWinAnimator, Mockito.never()).applyAnimationLocked(TRANSIT_EXIT, false);
+        verify(win.mWinAnimator, never()).applyAnimationLocked(TRANSIT_EXIT, false);
         assertTrue(win.mToken.hasChild());
 
         // Even though the window is being removed afterwards, it won't apply exit animation.
         win.removeIfPossible();
-        verify(win.mWinAnimator, Mockito.never()).applyAnimationLocked(TRANSIT_EXIT, false);
+        verify(win.mWinAnimator, never()).applyAnimationLocked(TRANSIT_EXIT, false);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+    public void onDisplayChanged_differentDisplay_reparented() {
+        final TestWindowToken token = createTestWindowToken(0, mDisplayContent);
+        final DisplayContent dc = mock(DisplayContent.class);
+        when(dc.getWindowToken(any())).thenReturn(null); // dc doesn't have this window token.
+
+        token.onDisplayChanged(dc);
+
+        verify(dc).reParentWindowToken(eq(token));
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+    public void onDisplayChanged_samedisplay_notReparented() {
+
+        final TestWindowToken token = createTestWindowToken(0, mDisplayContent);
+        final DisplayContent dc = mock(DisplayContent.class);
+        when(dc.getWindowToken(any())).thenReturn(mock(WindowToken.class));
+
+        token.onDisplayChanged(dc);
+
+        verify(dc, never()).reParentWindowToken(eq(token));
     }
 }
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 15c8b13..c65f784 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -70,6 +70,7 @@
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
+import android.os.SELinux;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UEventObserver;
@@ -161,6 +162,11 @@
     private static final String MIDI_ALSA_PATH =
             "/sys/class/android_usb/android0/f_midi/alsa";
 
+    /**
+     * The minimum SELinux genfs labels version that supports udc sysfs genfs context.
+     */
+    private static final int MIN_SELINUX_GENFS_LABELS_VERSION = 202404;
+
     private static final int MSG_UPDATE_STATE = 0;
     private static final int MSG_ENABLE_ADB = 1;
     private static final int MSG_SET_CURRENT_FUNCTIONS = 2;
@@ -445,7 +451,8 @@
 
         mEnableUdcSysfsUsbStateUpdate =
                 android.hardware.usb.flags.Flags.enableUdcSysfsUsbStateUpdate()
-                && context.getResources().getBoolean(R.bool.config_enableUdcSysfsUsbStateUpdate);
+                && context.getResources().getBoolean(R.bool.config_enableUdcSysfsUsbStateUpdate)
+                && SELinux.getGenfsLabelsVersion() > MIN_SELINUX_GENFS_LABELS_VERSION;
 
         if (mEnableUdcSysfsUsbStateUpdate) {
             mUEventObserver.startObserving(UDC_SUBSYS_MATCH);
diff --git a/telecomm/java/android/telecom/ParcelableCallAnalytics.java b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
index a69dfb0b..cdb3eaf 100644
--- a/telecomm/java/android/telecom/ParcelableCallAnalytics.java
+++ b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
@@ -16,12 +16,12 @@
 
 package android.telecom;
 
+import android.annotation.FlaggedApi;
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
 import java.util.ArrayList;
-import java.util.LinkedList;
 import java.util.List;
 
 /**
@@ -255,6 +255,11 @@
     public static final int CALLTYPE_OUTGOING = 2;
 
     // Constants for call technology
+    /**
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(com.android.internal.telephony.flags.Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CDMA_PHONE = 0x1;
     public static final int GSM_PHONE = 0x2;
     public static final int IMS_PHONE = 0x4;
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index 09b18b6..8fe107c 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -109,7 +109,6 @@
             //TelephonyManager.NETWORK_TYPE_LTE_CA,
 
             TelephonyManager.NETWORK_TYPE_NR,
-            TelephonyManager.NETWORK_TYPE_NB_IOT_NTN,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface NetworkType {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index e5f1841..fa4ec16 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -317,8 +317,10 @@
      * If this is set as false and the supplementary service menu is visible, the associated setting
      * will be enabled and disabled based on the availability of supplementary services over UT. See
      * {@link #KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL}.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final String KEY_SUPPORT_SS_OVER_CDMA_BOOL = "support_ss_over_cdma_bool";
 
     /**
@@ -536,7 +538,11 @@
      */
     public static final String KEY_4G_ONLY_BOOL = "4g_only_bool";
 
-    /** Show cdma network mode choices 1x, 3G, global etc. */
+    /** Show cdma network mode choices 1x, 3G, global etc.
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @Deprecated
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
     public static final String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool";
 
     /** CDMA activation goes through HFA */
@@ -544,9 +550,12 @@
 
     /**
      * CDMA activation goes through OTASP.
+     * @deprecated Legacy CDMA is unsupported.
      */
     // TODO: This should be combined with config_use_hfa_for_provisioning and implemented as an enum
     // (NONE, HFA, OTASP).
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final String KEY_USE_OTASP_FOR_PROVISIONING_BOOL =
             "use_otasp_for_provisioning_bool";
 
@@ -556,10 +565,20 @@
     /** Does not display additional call setting for IMS phone based on GSM Phone */
     public static final String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
 
-    /** Show APN Settings for some CDMA carriers */
+    /**
+     * Show APN Settings for some CDMA carriers
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @Deprecated
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
     public static final String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
 
-    /** After a CDMA conference call is merged, the swap button should be displayed. */
+    /**
+     * After a CDMA conference call is merged, the swap button should be displayed.
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @Deprecated
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
     public static final String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
 
     /**
@@ -597,7 +616,10 @@
     /**
      * Disables dialing "*228" (OTASP provisioning) on CDMA carriers where it is not supported or is
      * potentially harmful by locking the SIM to 3G.
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @Deprecated
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
     public static final String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL =
             "disable_cdma_activation_code_bool";
 
@@ -675,14 +697,20 @@
     /**
      * Override the platform's notion of a network operator being considered roaming.
      * Value is string array of SIDs to be considered roaming for 3GPP2 RATs.
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final String
             KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array";
 
     /**
      * Override the platform's notion of a network operator being considered non roaming.
      * Value is string array of SIDs to be considered not roaming for 3GPP2 RATs.
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final String
             KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
 
@@ -1243,8 +1271,10 @@
 
     /**
      * CDMA carrier ERI (Enhanced Roaming Indicator) file name
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final String KEY_CARRIER_ERI_FILE_NAME_STRING = "carrier_eri_file_name_string";
 
     /* The following 3 fields are related to carrier visual voicemail. */
@@ -1386,7 +1416,10 @@
      * Specifies the amount of gap to be added in millis between postdial DTMF tones. When a
      * non-zero value is specified, the UE shall wait for the specified amount of time before it
      * sends out successive DTMF tones on the network.
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
 
     /**
@@ -1804,8 +1837,10 @@
      * If this bit is not set, the carrier name display string will be selected from the carrier
      * display name resolver which doesn't apply the ERI rules.
      *
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final String KEY_ALLOW_ERI_BOOL = "allow_cdma_eri_bool";
 
     /**
@@ -1849,8 +1884,10 @@
      * If true, then the registered PLMN name (only for CDMA/CDMA-LTE and only when not roaming)
      * will be #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING. If false, or if phone type is not
      * CDMA/CDMA-LTE or if roaming, then #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING will be ignored.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final String KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL =
             "cdma_home_registered_plmn_name_override_bool";
 
@@ -1858,8 +1895,10 @@
      * String to identify registered PLMN name in CarrierConfig app. This string overrides
      * registered PLMN name if #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL is true, phone type
      * is CDMA/CDMA-LTE and device is not in roaming state; otherwise, it will be ignored.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final String KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING =
             "cdma_home_registered_plmn_name_string";
 
@@ -2440,7 +2479,10 @@
      * For carriers which require an empty flash to be sent before sending the normal 3-way calling
      * flash, the duration in milliseconds of the empty flash to send. When {@code 0}, no empty
      * flash is sent.
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final String KEY_CDMA_3WAYCALL_FLASH_DELAY_INT = "cdma_3waycall_flash_delay_int";
 
     /**
@@ -2454,14 +2496,21 @@
      * @see TelephonyManager#CDMA_ROAMING_MODE_HOME
      * @see TelephonyManager#CDMA_ROAMING_MODE_AFFILIATED
      * @see TelephonyManager#CDMA_ROAMING_MODE_ANY
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final String KEY_CDMA_ROAMING_MODE_INT = "cdma_roaming_mode_int";
 
     /**
      * Determines whether 1X voice calls is supported for some CDMA carriers.
      * Default value is true.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SystemApi
     public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL =
             "support_cdma_1x_voice_calls_bool";
@@ -2483,8 +2532,10 @@
     /**
      * Report IMEI as device id even if it's a CDMA/LTE phone.
      *
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final String KEY_FORCE_IMEI_BOOL = "force_imei_bool";
 
     /**
@@ -3217,8 +3268,10 @@
      * on a 3GPP network. Specifically *67<number> will be converted to #31#<number> and
      * *82<number> will be converted to *31#<number> before dialing a call when this key is
      * set TRUE and device is roaming on a 3GPP network.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final String KEY_CONVERT_CDMA_CALLER_ID_MMI_CODES_WHILE_ROAMING_ON_3GPP_BOOL =
             "convert_cdma_caller_id_mmi_codes_while_roaming_on_3gpp_bool";
 
@@ -3621,8 +3674,11 @@
     /**
      * Support for the original string display of CDMA MO call.
      * By default, it is disabled.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final String KEY_CONFIG_SHOW_ORIG_DIAL_STRING_FOR_CDMA_BOOL =
             "config_show_orig_dial_string_for_cdma";
 
@@ -5070,8 +5126,10 @@
      * The default values come from 3GPP2 C.R1001 table 8.1-1.
      * Enhanced Roaming Indicator Number Assignments
      *
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final String KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY =
             "cdma_enhanced_roaming_indicator_for_home_network_int_array";
 
@@ -9930,6 +9988,19 @@
             "satellite_data_support_mode_int";
 
     /**
+     * Determines whether data roaming off setting should be ignored and satellite data should be
+     * allowed even when data roaming is off.
+     *
+     * If the carrier would like to allow the device to use satellite connection when data roaming
+     * is off, this key should be set to {@code true}.
+     *
+     * The default value is {@code false} i.e. disallow satellite data when data roaming is off.
+     */
+    @FlaggedApi(Flags.FLAG_SATELLITE_25Q4_APIS)
+    public static final String KEY_SATELLITE_IGNORE_DATA_ROAMING_SETTING_BOOL =
+        "satellite_ignore_data_roaming_setting_bool";
+
+    /**
      * Determine whether to override roaming Wi-Fi Calling preference when device is connected to
      * non-terrestrial network.
      * {@code true}  - roaming preference cannot be changed by user independently.
@@ -11330,6 +11401,7 @@
         sDefaults.putBoolean(KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, true);
         sDefaults.putInt(KEY_SATELLITE_DATA_SUPPORT_MODE_INT,
                 CarrierConfigManager.SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED);
+        sDefaults.putBoolean(KEY_SATELLITE_IGNORE_DATA_ROAMING_SETTING_BOOL, false);
         sDefaults.putBoolean(KEY_OVERRIDE_WFC_ROAMING_MODE_WHILE_USING_NTN_BOOL, true);
         sDefaults.putInt(KEY_SATELLITE_ENTITLEMENT_STATUS_REFRESH_DAYS_INT, 7);
         sDefaults.putBoolean(KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, false);
diff --git a/telephony/java/android/telephony/CellBroadcastService.java b/telephony/java/android/telephony/CellBroadcastService.java
index 14de2f2..60f986c 100644
--- a/telephony/java/android/telephony/CellBroadcastService.java
+++ b/telephony/java/android/telephony/CellBroadcastService.java
@@ -17,6 +17,7 @@
 package android.telephony;
 
 import android.annotation.CallSuper;
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -28,6 +29,7 @@
 import android.os.RemoteCallback;
 import android.telephony.cdma.CdmaSmsCbProgramData;
 
+import com.android.internal.telephony.flags.Flags;
 import com.android.internal.util.FastPrintWriter;
 
 import java.io.FileDescriptor;
@@ -88,9 +90,12 @@
      * @param slotIndex       the index of the slot which received the message
      * @param bearerData      the CDMA SMS bearer data
      * @param serviceCategory the CDMA SCPT service category
+     * @deprecated Legacy CDMA is unsupported.
      */
-    public abstract void onCdmaCellBroadcastSms(int slotIndex, @NonNull byte[] bearerData,
-            @CdmaSmsCbProgramData.Category int serviceCategory);
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
+    public void onCdmaCellBroadcastSms(int slotIndex, @NonNull byte[] bearerData,
+            @CdmaSmsCbProgramData.Category int serviceCategory) {}
 
     /**
      * Handle a CDMA cell broadcast SMS message forwarded from the system.
@@ -102,10 +107,13 @@
      * @param callback           a callback to run after each cell broadcast receiver has handled
      *                           the SCP message. The bundle will contain a non-separated
      *                           dial string as and an ArrayList of {@link CdmaSmsCbProgramResults}.
+     * @deprecated Legacy CDMA is unsupported.
      */
-    public abstract void onCdmaScpMessage(int slotIndex,
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
+    public void onCdmaScpMessage(int slotIndex,
             @NonNull List<CdmaSmsCbProgramData> smsCbProgramData,
-            @NonNull String originatingAddress, @NonNull Consumer<Bundle> callback);
+            @NonNull String originatingAddress, @NonNull Consumer<Bundle> callback) {}
 
     /**
      * Get broadcasted area information.
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index 5eace54..4cb622b 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -18,11 +18,13 @@
 
 import static android.text.TextUtils.formatSimple;
 
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.Parcel;
 import android.telephony.cdma.CdmaCellLocation;
 
+import com.android.internal.telephony.flags.Flags;
 import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.telephony.Rlog;
 
@@ -30,7 +32,11 @@
 
 /**
  * CellIdentity is to represent a unique CDMA cell
+ *
+ * @deprecated Legacy CDMA is unsupported.
  */
+@FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+@Deprecated
 public final class CellIdentityCdma extends CellIdentity {
     private static final String TAG = CellIdentityCdma.class.getSimpleName();
     private static final boolean DBG = false;
@@ -99,20 +105,30 @@
      */
     public CellIdentityCdma(int nid, int sid, int bid, int lon, int lat,
             @Nullable String alphal, @Nullable String alphas) {
-        super(TAG, CellInfo.TYPE_CDMA, null, null, alphal, alphas);
-        mNetworkId = inRangeOrUnavailable(nid, 0, NETWORK_ID_MAX);
-        mSystemId = inRangeOrUnavailable(sid, 0, SYSTEM_ID_MAX);
-        mBasestationId = inRangeOrUnavailable(bid, 0, BASESTATION_ID_MAX);
-        lat = inRangeOrUnavailable(lat, LATITUDE_MIN, LATITUDE_MAX);
-        lon = inRangeOrUnavailable(lon, LONGITUDE_MIN, LONGITUDE_MAX);
-
-        if (!isNullIsland(lat, lon)) {
-            mLongitude = lon;
-            mLatitude = lat;
+        super(TAG, CellInfo.TYPE_CDMA, null, null, Flags.cleanupCdma() ? null : alphal,
+                Flags.cleanupCdma() ? null : alphas);
+        if (Flags.cleanupCdma()) {
+            mNetworkId = CellInfo.UNAVAILABLE;
+            mSystemId = CellInfo.UNAVAILABLE;
+            mBasestationId = CellInfo.UNAVAILABLE;
+            mLongitude = CellInfo.UNAVAILABLE;
+            mLatitude = CellInfo.UNAVAILABLE;
+            mGlobalCellId = null;
         } else {
-            mLongitude = mLatitude = CellInfo.UNAVAILABLE;
+            mNetworkId = inRangeOrUnavailable(nid, 0, NETWORK_ID_MAX);
+            mSystemId = inRangeOrUnavailable(sid, 0, SYSTEM_ID_MAX);
+            mBasestationId = inRangeOrUnavailable(bid, 0, BASESTATION_ID_MAX);
+            lat = inRangeOrUnavailable(lat, LATITUDE_MIN, LATITUDE_MAX);
+            lon = inRangeOrUnavailable(lon, LONGITUDE_MIN, LONGITUDE_MAX);
+
+            if (!isNullIsland(lat, lon)) {
+                mLongitude = lon;
+                mLatitude = lat;
+            } else {
+                mLongitude = mLatitude = CellInfo.UNAVAILABLE;
+            }
+            updateGlobalCellId();
         }
-        updateGlobalCellId();
     }
 
     private CellIdentityCdma(@NonNull CellIdentityCdma cid) {
@@ -124,7 +140,11 @@
         return new CellIdentityCdma(this);
     }
 
-    /** @hide */
+    /** @hide
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @Override
     public @NonNull CellIdentityCdma sanitizeLocationInfo() {
         return new CellIdentityCdma(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
@@ -157,7 +177,11 @@
     /**
      * @return Network Id 0..65535, {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE}
      *         if unavailable.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public int getNetworkId() {
         return mNetworkId;
     }
@@ -165,7 +189,11 @@
     /**
      * @return System Id 0..32767, {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE}
      *         if unavailable.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public int getSystemId() {
         return mSystemId;
     }
@@ -173,7 +201,10 @@
     /**
      * @return Base Station Id 0..65535, {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE}
      *         if unavailable.
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public int getBasestationId() {
         return mBasestationId;
     }
@@ -184,7 +215,11 @@
      * of 0.25 seconds and ranges from -2592000 to 2592000, both
      * values inclusive (corresponding to a range of -180
      * to +180 degrees). {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public int getLongitude() {
         return mLongitude;
     }
@@ -195,7 +230,11 @@
      * of 0.25 seconds and ranges from -1296000 to 1296000, both
      * values inclusive (corresponding to a range of -90
      * to +90 degrees). {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public int getLatitude() {
         return mLatitude;
     }
@@ -206,7 +245,11 @@
                 super.hashCode());
     }
 
-    /** @hide */
+    /** @hide
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @NonNull
     @Override
     public CdmaCellLocation asCellLocation() {
@@ -267,17 +310,43 @@
     /** Construct from Parcel, type has already been processed */
     private CellIdentityCdma(Parcel in) {
         super(TAG, CellInfo.TYPE_CDMA, in);
-        mNetworkId = in.readInt();
-        mSystemId = in.readInt();
-        mBasestationId = in.readInt();
-        mLongitude = in.readInt();
-        mLatitude = in.readInt();
 
-        updateGlobalCellId();
-        if (DBG) log(toString());
+        if (Flags.cleanupCdma()) {
+            in.readInt();
+            mNetworkId = CellInfo.UNAVAILABLE;
+
+            in.readInt();
+            mSystemId = CellInfo.UNAVAILABLE;
+
+            in.readInt();
+            mBasestationId = CellInfo.UNAVAILABLE;
+
+            in.readInt();
+            mLongitude = CellInfo.UNAVAILABLE;
+
+            in.readInt();
+            mLatitude = CellInfo.UNAVAILABLE;
+
+            mGlobalCellId = null;
+        } else {
+            mNetworkId = in.readInt();
+            mSystemId = in.readInt();
+            mBasestationId = in.readInt();
+            mLongitude = in.readInt();
+            mLatitude = in.readInt();
+
+            updateGlobalCellId();
+            if (DBG) log(toString());
+        }
     }
 
-    /** Implement the Parcelable interface */
+    /**
+     * Implement the Parcelable interface
+     *
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SuppressWarnings("hiding")
     public static final @android.annotation.NonNull Creator<CellIdentityCdma> CREATOR =
             new Creator<CellIdentityCdma>() {
diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java
index aa8cff5..3c4bb51 100644
--- a/telephony/java/android/telephony/CellInfoCdma.java
+++ b/telephony/java/android/telephony/CellInfoCdma.java
@@ -16,17 +16,23 @@
 
 package android.telephony;
 
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.internal.telephony.flags.Flags;
 import com.android.telephony.Rlog;
 
 /**
  * A {@link CellInfo} representing a CDMA cell that provides identity and measurement info.
+ *
+ * @deprecated Legacy CDMA is unsupported.
  */
+@FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+@Deprecated
 public final class CellInfoCdma extends CellInfo implements Parcelable {
 
     private static final String LOG_TAG = "CellInfoCdma";
@@ -61,7 +67,10 @@
 
     /**
      * @return a {@link CellIdentityCdma} instance.
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @Override
     public @NonNull CellIdentityCdma getCellIdentity() {
         return mCellIdentityCdma;
@@ -75,7 +84,10 @@
 
     /**
      * @return a {@link CellSignalStrengthCdma} instance.
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @Override
     public @NonNull CellSignalStrengthCdma getCellSignalStrength() {
         return mCellSignalStrengthCdma;
@@ -135,7 +147,12 @@
         return 0;
     }
 
-    /** Implement the Parcelable interface */
+    /**
+     * Implement the Parcelable interface
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         super.writeToParcel(dest, flags, TYPE_CDMA);
@@ -154,7 +171,12 @@
         if (DBG) log("CellInfoCdma(Parcel): " + toString());
     }
 
-    /** Implement the Parcelable interface */
+    /**
+     * Implement the Parcelable interface
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final @android.annotation.NonNull Creator<CellInfoCdma> CREATOR = new Creator<CellInfoCdma>() {
         @Override
         public CellInfoCdma createFromParcel(Parcel in) {
diff --git a/telephony/java/android/telephony/CellSignalStrengthCdma.java b/telephony/java/android/telephony/CellSignalStrengthCdma.java
index 5298e67..12a7294 100644
--- a/telephony/java/android/telephony/CellSignalStrengthCdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthCdma.java
@@ -21,6 +21,7 @@
 import android.os.Parcelable;
 import android.os.PersistableBundle;
 
+import com.android.internal.telephony.flags.Flags;
 import com.android.telephony.Rlog;
 
 import java.util.Objects;
@@ -68,13 +69,17 @@
      */
     public CellSignalStrengthCdma(int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio,
             int evdoSnr) {
-        mCdmaDbm = inRangeOrUnavailable(cdmaDbm, -120, 0);
-        mCdmaEcio = inRangeOrUnavailable(cdmaEcio, -160, 0);
-        mEvdoDbm = inRangeOrUnavailable(evdoDbm, -120, 0);
-        mEvdoEcio = inRangeOrUnavailable(evdoEcio, -160, 0);
-        mEvdoSnr = inRangeOrUnavailable(evdoSnr, 0, 8);
+        if (Flags.cleanupCdma()) {
+            setDefaultValues();
+        } else {
+            mCdmaDbm = inRangeOrUnavailable(cdmaDbm, -120, 0);
+            mCdmaEcio = inRangeOrUnavailable(cdmaEcio, -160, 0);
+            mEvdoDbm = inRangeOrUnavailable(evdoDbm, -120, 0);
+            mEvdoEcio = inRangeOrUnavailable(evdoEcio, -160, 0);
+            mEvdoSnr = inRangeOrUnavailable(evdoSnr, 0, 8);
 
-        updateLevel(null, null);
+            updateLevel(null, null);
+        }
     }
 
     /** @hide */
@@ -84,6 +89,10 @@
 
     /** @hide */
     protected void copyFrom(CellSignalStrengthCdma s) {
+        if (Flags.cleanupCdma()) {
+            setDefaultValues();
+            return;
+        }
         mCdmaDbm = s.mCdmaDbm;
         mCdmaEcio = s.mCdmaEcio;
         mEvdoDbm = s.mEvdoDbm;
@@ -389,6 +398,7 @@
     /** @hide */
     @Override
     public boolean isValid() {
+        if (Flags.cleanupCdma()) return false;
         return !this.equals(sInvalid);
     }
 
@@ -446,7 +456,12 @@
         mEvdoEcio = in.readInt();
         mEvdoSnr = in.readInt();
         mLevel = in.readInt();
-        if (DBG) log("CellSignalStrengthCdma(Parcel): " + toString());
+
+        if (Flags.cleanupCdma()) {
+            setDefaultValues();
+        } else {
+            if (DBG) log("CellSignalStrengthCdma(Parcel): " + toString());
+        }
     }
 
     /** Implement the Parcelable interface */
diff --git a/telephony/java/android/telephony/PreciseDisconnectCause.java b/telephony/java/android/telephony/PreciseDisconnectCause.java
index d9437ab..2d650ab2 100644
--- a/telephony/java/android/telephony/PreciseDisconnectCause.java
+++ b/telephony/java/android/telephony/PreciseDisconnectCause.java
@@ -255,25 +255,75 @@
     @FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE)
     public static final int EMERGENCY_PERM_FAILURE                           = 326;
 
-    /** Mobile station (MS) is locked until next power cycle. */
+    /**
+     * Mobile station (MS) is locked until next power cycle.
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE                    = 1000;
-    /** Drop call. */
+    /**
+     * Drop call.
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CDMA_DROP                                        = 1001;
-    /** INTERCEPT order received, Mobile station (MS) state idle entered. */
+    /**
+     * INTERCEPT order received, Mobile station (MS) state idle entered.
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CDMA_INTERCEPT                                   = 1002;
-    /** Mobile station (MS) has been redirected, call is cancelled. */
+    /**
+     * Mobile station (MS) has been redirected, call is cancelled.
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CDMA_REORDER                                     = 1003;
-    /** Service option rejection. */
+    /**
+     * Service option rejection.
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CDMA_SO_REJECT                                   = 1004;
-    /** Requested service is rejected, retry delay is set. */
+    /**
+     * Requested service is rejected, retry delay is set.
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CDMA_RETRY_ORDER                                 = 1005;
-    /** Unable to obtain access to the CDMA system. */
+    /**
+     * Unable to obtain access to the CDMA system.
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CDMA_ACCESS_FAILURE                              = 1006;
-    /** Not a preempted call. */
+    /**
+     * Not a preempted call.
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CDMA_PREEMPTED                                   = 1007;
-    /** Not an emergency call. */
+    /**
+     * Not an emergency call.
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CDMA_NOT_EMERGENCY                               = 1008;
-    /** Access Blocked by CDMA network. */
+    /**
+     * Access Blocked by CDMA network.
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CDMA_ACCESS_BLOCKED                              = 1009;
 
     /* OEM specific error codes. To be used by OEMs when they don't want to
diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java
index 8b52f07..90d6f89 100644
--- a/telephony/java/android/telephony/RadioAccessFamily.java
+++ b/telephony/java/android/telephony/RadioAccessFamily.java
@@ -66,9 +66,6 @@
     // 5G
     public static final int RAF_NR = (int) TelephonyManager.NETWORK_TYPE_BITMASK_NR;
 
-    /** NB-IOT (Narrowband Internet of Things) over Non-Terrestrial-Networks technology. */
-    public static final int RAF_NB_IOT_NTN = (int) TelephonyManager.NETWORK_TYPE_BITMASK_NB_IOT_NTN;
-
     // Grouping of RAFs
     // 2G
     private static final int GSM = RAF_GSM | RAF_GPRS | RAF_EDGE;
@@ -83,9 +80,6 @@
     // 5G
     private static final int NR = RAF_NR;
 
-    /** Non-Terrestrial Network. */
-    private static final int NB_IOT_NTN = RAF_NB_IOT_NTN;
-
     /* Phone ID of phone */
     private int mPhoneId;
 
@@ -264,7 +258,7 @@
         raf = ((EVDO & raf) > 0) ? (EVDO | raf) : raf;
         raf = ((LTE & raf) > 0) ? (LTE | raf) : raf;
         raf = ((NR & raf) > 0) ? (NR | raf) : raf;
-        raf = ((NB_IOT_NTN & raf) > 0) ? (NB_IOT_NTN | raf) : raf;
+
         return raf;
     }
 
@@ -370,7 +364,6 @@
             case "WCDMA":   return WCDMA;
             case "LTE_CA":  return RAF_LTE_CA;
             case "NR":      return RAF_NR;
-            case "NB_IOT_NTN": return RAF_NB_IOT_NTN;
             default:        return RAF_UNKNOWN;
         }
     }
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index f8c3287..127bbff 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -233,12 +233,6 @@
     public static final int  RIL_RADIO_TECHNOLOGY_NR = 20;
 
     /**
-     * 3GPP NB-IOT (Narrowband Internet of Things) over Non-Terrestrial-Networks technology.
-     * @hide
-     */
-    public static final int RIL_RADIO_TECHNOLOGY_NB_IOT_NTN = 21;
-
-    /**
      * RIL Radio Annotation
      * @hide
      */
@@ -264,16 +258,14 @@
         ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA,
         ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN,
         ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA,
-        ServiceState.RIL_RADIO_TECHNOLOGY_NR,
-        ServiceState.RIL_RADIO_TECHNOLOGY_NB_IOT_NTN
-    })
+        ServiceState.RIL_RADIO_TECHNOLOGY_NR})
     public @interface RilRadioTechnology {}
 
 
     /**
      * The number of the radio technologies.
      */
-    private static final int NEXT_RIL_RADIO_TECHNOLOGY = 22;
+    private static final int NEXT_RIL_RADIO_TECHNOLOGY = 21;
 
     /** @hide */
     public static final int RIL_RADIO_CDMA_TECHNOLOGY_BITMASK =
@@ -1133,9 +1125,6 @@
             case RIL_RADIO_TECHNOLOGY_NR:
                 rtString = "NR_SA";
                 break;
-            case RIL_RADIO_TECHNOLOGY_NB_IOT_NTN:
-                rtString = "NB_IOT_NTN";
-                break;
             default:
                 rtString = "Unexpected";
                 Rlog.w(LOG_TAG, "Unexpected radioTechnology=" + rt);
@@ -1679,8 +1668,6 @@
                 return TelephonyManager.NETWORK_TYPE_LTE_CA;
             case RIL_RADIO_TECHNOLOGY_NR:
                 return TelephonyManager.NETWORK_TYPE_NR;
-            case RIL_RADIO_TECHNOLOGY_NB_IOT_NTN:
-                return TelephonyManager.NETWORK_TYPE_NB_IOT_NTN;
             default:
                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
         }
@@ -1710,7 +1697,6 @@
                 return AccessNetworkType.CDMA2000;
             case RIL_RADIO_TECHNOLOGY_LTE:
             case RIL_RADIO_TECHNOLOGY_LTE_CA:
-            case RIL_RADIO_TECHNOLOGY_NB_IOT_NTN:
                 return AccessNetworkType.EUTRAN;
             case RIL_RADIO_TECHNOLOGY_NR:
                 return AccessNetworkType.NGRAN;
@@ -1771,8 +1757,6 @@
                 return RIL_RADIO_TECHNOLOGY_LTE_CA;
             case TelephonyManager.NETWORK_TYPE_NR:
                 return RIL_RADIO_TECHNOLOGY_NR;
-            case TelephonyManager.NETWORK_TYPE_NB_IOT_NTN:
-                return RIL_RADIO_TECHNOLOGY_NB_IOT_NTN;
             default:
                 return RIL_RADIO_TECHNOLOGY_UNKNOWN;
         }
@@ -1882,8 +1866,7 @@
                 || radioTechnology == RIL_RADIO_TECHNOLOGY_TD_SCDMA
                 || radioTechnology == RIL_RADIO_TECHNOLOGY_IWLAN
                 || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA
-                || radioTechnology == RIL_RADIO_TECHNOLOGY_NR
-                || radioTechnology == RIL_RADIO_TECHNOLOGY_NB_IOT_NTN;
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_NR;
 
     }
 
@@ -1903,8 +1886,7 @@
     public static boolean isPsOnlyTech(int radioTechnology) {
         return radioTechnology == RIL_RADIO_TECHNOLOGY_LTE
                 || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA
-                || radioTechnology == RIL_RADIO_TECHNOLOGY_NR
-                || radioTechnology == RIL_RADIO_TECHNOLOGY_NB_IOT_NTN;
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_NR;
     }
 
     /** @hide */
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index aec11c4..24fb8c5 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1397,25 +1397,44 @@
     /**
      * Value for {@link CarrierConfigManager#KEY_CDMA_ROAMING_MODE_INT} which leaves the roaming
      * mode set to the radio default or to the user's preference if they've indicated one.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CDMA_ROAMING_MODE_RADIO_DEFAULT = -1;
     /**
      * Value for {@link CarrierConfigManager#KEY_CDMA_ROAMING_MODE_INT} which only permits
      * connections on home networks.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CDMA_ROAMING_MODE_HOME = 0;
     /**
      * Value for {@link CarrierConfigManager#KEY_CDMA_ROAMING_MODE_INT} which permits roaming on
      * affiliated networks.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CDMA_ROAMING_MODE_AFFILIATED = 1;
     /**
      * Value for {@link CarrierConfigManager#KEY_CDMA_ROAMING_MODE_INT} which permits roaming on
      * any network.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CDMA_ROAMING_MODE_ANY = 2;
 
-    /** @hide */
+    /** @hide
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @Deprecated
     @IntDef(prefix = { "CDMA_ROAMING_MODE_" }, value = {
             CDMA_ROAMING_MODE_RADIO_DEFAULT,
             CDMA_ROAMING_MODE_HOME,
@@ -1802,12 +1821,17 @@
      * to indicate if the SIM combination in DSDS has limitation or compatible issue.
      * e.g. two CDMA SIMs may disrupt each other's voice call in certain scenarios.
      *
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final String EXTRA_SIM_COMBINATION_WARNING_TYPE =
             "android.telephony.extra.SIM_COMBINATION_WARNING_TYPE";
 
-    /** @hide */
+    /** @hide
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @Deprecated
     @IntDef({
             EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE,
             EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA
@@ -1818,15 +1842,21 @@
     /**
      * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE}
      * to indicate there's no SIM combination warning.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE = 0;
 
     /**
      * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE}
      * to indicate two active SIMs are both CDMA hence there might be functional limitation.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA = 1;
 
     /**
@@ -1835,6 +1865,7 @@
      * e.g. two CDMA SIMs may disrupt each other's voice call in certain scenarios, and the
      * name will be "operator1 & operator2".
      *
+     * TODO(b/379356026): Deprecate if this is CDMA specific
      * @hide
      */
     public static final String EXTRA_SIM_COMBINATION_NAMES =
@@ -2414,13 +2445,17 @@
      *     higher, then a SecurityException is thrown.</li>
      * </ul>
      *
+     * @deprecated Legacy CDMA is unsupported.
      * @throws UnsupportedOperationException If the device does not have
      *          {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public String getMeid() {
+        if (Flags.cleanupCdma()) return null;
         return getMeid(getSlotIndex());
     }
 
@@ -2456,13 +2491,17 @@
      *
      * @param slotIndex of which MEID is returned
      *
+     * @deprecated Legacy CDMA is unsupported.
      * @throws UnsupportedOperationException If the device does not have
      *          {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public String getMeid(int slotIndex) {
+        if (Flags.cleanupCdma()) return null;
         ITelephony telephony = getITelephony();
         if (telephony == null) return null;
 
@@ -2485,12 +2524,16 @@
      * Returns the Manufacturer Code from the MEID. Return null if Manufacturer Code is not
      * available.
      *
+     * @deprecated Legacy CDMA is unsupported.
      * @throws UnsupportedOperationException If the device does not have
      *          {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     @Nullable
     public String getManufacturerCode() {
+        if (Flags.cleanupCdma()) return null;
         return getManufacturerCode(getSlotIndex());
     }
 
@@ -2500,12 +2543,16 @@
      *
      * @param slotIndex of which Type Allocation Code is returned
      *
+     * @deprecated Legacy CDMA is unsupported.
      * @throws UnsupportedOperationException If the device does not have
      *          {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     @Nullable
     public String getManufacturerCode(int slotIndex) {
+        if (Flags.cleanupCdma()) return null;
         ITelephony telephony = getITelephony();
         if (telephony == null) return null;
 
@@ -2648,7 +2695,13 @@
     public static final int PHONE_TYPE_NONE = PhoneConstants.PHONE_TYPE_NONE;
     /** Phone radio is GSM. */
     public static final int PHONE_TYPE_GSM = PhoneConstants.PHONE_TYPE_GSM;
-    /** Phone radio is CDMA. */
+    /**
+     * Phone radio is CDMA.
+     *
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int PHONE_TYPE_CDMA = PhoneConstants.PHONE_TYPE_CDMA;
     /** Phone is via SIP. */
     public static final int PHONE_TYPE_SIP = PhoneConstants.PHONE_TYPE_SIP;
@@ -3070,13 +3123,33 @@
     public static final int NETWORK_TYPE_EDGE = TelephonyProtoEnums.NETWORK_TYPE_EDGE; // = 2.
     /** Current network is UMTS */
     public static final int NETWORK_TYPE_UMTS = TelephonyProtoEnums.NETWORK_TYPE_UMTS; // = 3.
-    /** Current network is CDMA: Either IS95A or IS95B*/
+    /**
+     * Current network is CDMA: Either IS95A or IS95B
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int NETWORK_TYPE_CDMA = TelephonyProtoEnums.NETWORK_TYPE_CDMA; // = 4.
-    /** Current network is EVDO revision 0*/
+    /**
+     * Current network is EVDO revision 0
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int NETWORK_TYPE_EVDO_0 = TelephonyProtoEnums.NETWORK_TYPE_EVDO_0; // = 5.
-    /** Current network is EVDO revision A*/
+    /**
+     * Current network is EVDO revision A
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int NETWORK_TYPE_EVDO_A = TelephonyProtoEnums.NETWORK_TYPE_EVDO_A; // = 6.
-    /** Current network is 1xRTT*/
+    /**
+     * Current network is 1xRTT
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int NETWORK_TYPE_1xRTT = TelephonyProtoEnums.NETWORK_TYPE_1XRTT; // = 7.
     /** Current network is HSDPA */
     public static final int NETWORK_TYPE_HSDPA = TelephonyProtoEnums.NETWORK_TYPE_HSDPA; // = 8.
@@ -3090,11 +3163,21 @@
      */
     @Deprecated
     public static final int NETWORK_TYPE_IDEN = TelephonyProtoEnums.NETWORK_TYPE_IDEN; // = 11.
-    /** Current network is EVDO revision B*/
+    /**
+     * Current network is EVDO revision B
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int NETWORK_TYPE_EVDO_B = TelephonyProtoEnums.NETWORK_TYPE_EVDO_B; // = 12.
     /** Current network is LTE */
     public static final int NETWORK_TYPE_LTE = TelephonyProtoEnums.NETWORK_TYPE_LTE; // = 13.
-    /** Current network is eHRPD */
+    /**
+     * Current network is eHRPD
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int NETWORK_TYPE_EHRPD = TelephonyProtoEnums.NETWORK_TYPE_EHRPD; // = 14.
     /** Current network is HSPA+ */
     public static final int NETWORK_TYPE_HSPAP = TelephonyProtoEnums.NETWORK_TYPE_HSPAP; // = 15.
@@ -3114,12 +3197,6 @@
      * For 5G NSA, the network type will be {@link #NETWORK_TYPE_LTE}.
      */
     public static final int NETWORK_TYPE_NR = TelephonyProtoEnums.NETWORK_TYPE_NR; // 20.
-    /**
-     * 3GPP NB-IOT (Narrowband Internet of Things) over Non-Terrestrial-Networks technology.
-     */
-    @FlaggedApi(Flags.FLAG_SATELLITE_SYSTEM_APIS)
-    public static final int NETWORK_TYPE_NB_IOT_NTN =
-            TelephonyProtoEnums.NETWORK_TYPE_NB_IOT_NTN; // 21
 
     private static final @NetworkType int[] NETWORK_TYPES = {
             NETWORK_TYPE_GPRS,
@@ -3196,7 +3273,6 @@
      * @see #NETWORK_TYPE_EHRPD
      * @see #NETWORK_TYPE_HSPAP
      * @see #NETWORK_TYPE_NR
-     * @see #NETWORK_TYPE_NB_IOT_NTN
      *
      * @hide
      */
@@ -3257,7 +3333,6 @@
      * @see #NETWORK_TYPE_EHRPD
      * @see #NETWORK_TYPE_HSPAP
      * @see #NETWORK_TYPE_NR
-     * @see #NETWORK_TYPE_NB_IOT_NTN
      *
      * @throws UnsupportedOperationException If the device does not have
      *          {@link PackageManager#FEATURE_TELEPHONY_RADIO_ACCESS}.
@@ -3408,8 +3483,6 @@
                 return "LTE_CA";
             case NETWORK_TYPE_NR:
                 return "NR";
-            case NETWORK_TYPE_NB_IOT_NTN:
-                return "NB_IOT_NTN";
             case NETWORK_TYPE_UNKNOWN:
                 return "UNKNOWN";
             default:
@@ -3460,8 +3533,6 @@
                 return NETWORK_TYPE_BITMASK_LTE;
             case NETWORK_TYPE_NR:
                 return NETWORK_TYPE_BITMASK_NR;
-            case NETWORK_TYPE_NB_IOT_NTN:
-                return NETWORK_TYPE_BITMASK_NB_IOT_NTN;
             case NETWORK_TYPE_IWLAN:
                 return NETWORK_TYPE_BITMASK_IWLAN;
             case NETWORK_TYPE_IDEN:
@@ -6304,6 +6375,7 @@
      * @deprecated use {@link #getImsPrivateUserIdentity()}
      */
     @UnsupportedAppUsage
+    @Deprecated
     public String getIsimImpi() {
         try {
             IPhoneSubInfo info = getSubscriberInfoService();
@@ -6393,6 +6465,7 @@
      * @deprecated use {@link #getImsPublicUserIdentities()}
      */
     @UnsupportedAppUsage
+    @Deprecated
     @Nullable
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public String[] getIsimImpu() {
@@ -6773,9 +6846,13 @@
         }
     }
 
-    /** @hide */
+    /** @hide
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @Deprecated
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"ERI_"}, value = {
+            -1,
             ERI_ON,
             ERI_OFF,
             ERI_FLASH
@@ -6785,24 +6862,37 @@
     /**
      * ERI (Enhanced Roaming Indicator) is ON i.e value 0 defined by
      * 3GPP2 C.R1001-H v1.0 Table 8.1-1.
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int ERI_ON = 0;
 
     /**
      * ERI (Enhanced Roaming Indicator) is OFF i.e value 1 defined by
      * 3GPP2 C.R1001-H v1.0 Table 8.1-1.
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int ERI_OFF = 1;
 
     /**
      * ERI (Enhanced Roaming Indicator) is FLASH i.e value 2 defined by
      * 3GPP2 C.R1001-H v1.0 Table 8.1-1.
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int ERI_FLASH = 2;
 
-    /** @hide */
+    /** @hide
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @Deprecated
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"ERI_ICON_MODE_"}, value = {
+            -1,
             ERI_ICON_MODE_NORMAL,
             ERI_ICON_MODE_FLASH
     })
@@ -6814,7 +6904,9 @@
      *
      * Note: ERI is defined 3GPP2 C.R1001-H Table 8.1-1
      * @hide
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @Deprecated
     public static final int ERI_ICON_MODE_NORMAL = 0;
 
     /**
@@ -6823,7 +6915,9 @@
      *
      * Note: ERI is defined 3GPP2 C.R1001-H Table 8.1-1
      * @hide
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @Deprecated
     public static final int ERI_ICON_MODE_FLASH = 1;
 
     /**
@@ -6831,24 +6925,31 @@
      * 3GPP2 C.R1001-H v1.0 Table 8.1-1. Additionally carriers define their own ERI display numbers.
      * Defined values are {@link #ERI_ON}, {@link #ERI_OFF}, and {@link #ERI_FLASH}.
      *
+     * @deprecated Legacy CDMA is unsupported.
      * @throws UnsupportedOperationException If the device does not have
      *          {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
      * @hide
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public @EriIconIndex int getCdmaEnhancedRoamingIndicatorDisplayNumber() {
+        if (Flags.cleanupCdma()) return -1;
         return getCdmaEriIconIndex(getSubId());
     }
 
     /**
      * Returns the CDMA ERI icon index to display for a subscription.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @UnsupportedAppUsage
     public @EriIconIndex int getCdmaEriIconIndex(int subId) {
+        if (Flags.cleanupCdma()) return -1;
         try {
             ITelephony telephony = getITelephony();
             if (telephony == null)
@@ -6868,11 +6969,14 @@
      * 0 - ON
      * 1 - FLASHING
      *
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @UnsupportedAppUsage
     public @EriIconMode int getCdmaEriIconMode(int subId) {
+        if (Flags.cleanupCdma()) return -1;
         try {
             ITelephony telephony = getITelephony();
             if (telephony == null)
@@ -6890,21 +6994,27 @@
     /**
      * Returns the CDMA ERI text,
      *
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getCdmaEriText() {
+        if (Flags.cleanupCdma()) return null;
         return getCdmaEriText(getSubId());
     }
 
     /**
      * Returns the CDMA ERI text, of a subscription
      *
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     @UnsupportedAppUsage
     public String getCdmaEriText(int subId) {
+        if (Flags.cleanupCdma()) return null;
         try {
             ITelephony telephony = getITelephony();
             if (telephony == null)
@@ -8178,10 +8288,13 @@
      * @param itemID the ID of the item to read.
      * @return the NV item as a String, or null on any failure.
      *
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     @UnsupportedAppUsage
     public String nvReadItem(int itemID) {
+        if (Flags.cleanupCdma()) return "";
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null)
@@ -8206,9 +8319,12 @@
      * @param itemValue the value to write, as a String.
      * @return true on success; false on any failure.
      *
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public boolean nvWriteItem(int itemID, String itemValue) {
+        if (Flags.cleanupCdma()) return false;
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null)
@@ -8232,9 +8348,12 @@
      * @param preferredRoamingList byte array containing the new PRL.
      * @return true on success; false on any failure.
      *
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
+        if (Flags.cleanupCdma()) return false;
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null)
@@ -8260,12 +8379,19 @@
      * {@link #resetRadioConfig()} for reset type 3 (b/116476729)
      *
      * @param resetType reset type: 1: reload NV reset, 2: erase NV reset, 3: factory NV reset
+     * @deprecated NV APIs are deprecated starting from Android U.
      * @return true on success; false on any failure.
      *
      * @hide
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @Deprecated
     public boolean nvResetConfig(int resetType) {
+        if (Flags.cleanupCdma()) {
+            if (resetType != 1) {  // 1: reload NV reset (reboot modem)
+                return false;
+            }
+        }
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
@@ -8295,14 +8421,20 @@
      *
      * @return {@code true} on success; {@code false} on any failure.
      *
+     * @deprecated NV APIs are deprecated starting from Android U.
      * @throws UnsupportedOperationException If the device does not have
      *          {@link PackageManager#FEATURE_TELEPHONY_RADIO_ACCESS}.
      * @hide
      */
+    @Deprecated
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     @SystemApi
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public boolean resetRadioConfig() {
+        if (Flags.cleanupCdma()) {
+            return false;
+        }
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
@@ -8331,6 +8463,7 @@
      *          {@link PackageManager#FEATURE_TELEPHONY_RADIO_ACCESS}.
      * @hide
      */
+    @Deprecated
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     @SystemApi
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
@@ -8367,7 +8500,9 @@
             if (telephony == null) {
                 throw new IllegalStateException("telephony service is null.");
             }
-            telephony.rebootModem(getSlotIndex());
+            if (!telephony.rebootModem(getSlotIndex())) {
+                throw new RuntimeException("Couldn't reboot modem (it may be not supported)");
+            }
         } catch (RemoteException ex) {
             Rlog.e(TAG, "rebootRadio RemoteException", ex);
             throw ex.rethrowAsRuntimeException();
@@ -9284,20 +9419,26 @@
 
     /**
      * Preferred network mode is CDMA and EvDo (auto mode, according to PRL).
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final int NETWORK_MODE_CDMA_EVDO = RILConstants.NETWORK_MODE_CDMA;
 
     /**
      * Preferred network mode is CDMA only.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final int NETWORK_MODE_CDMA_NO_EVDO = RILConstants.NETWORK_MODE_CDMA_NO_EVDO;
 
     /**
      * Preferred network mode is EvDo only.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final int NETWORK_MODE_EVDO_NO_CDMA = RILConstants.NETWORK_MODE_EVDO_NO_CDMA;
 
     /**
@@ -9308,8 +9449,10 @@
 
     /**
      * Preferred network mode is LTE, CDMA and EvDo.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final int NETWORK_MODE_LTE_CDMA_EVDO = RILConstants.NETWORK_MODE_LTE_CDMA_EVDO;
 
     /**
@@ -9320,8 +9463,10 @@
 
     /**
      * Preferred network mode is LTE, CDMA, EvDo, GSM/WCDMA.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA =
             RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA;
 
@@ -9391,14 +9536,18 @@
 
     /**
      * Preferred network mode is TD-SCDMA,EvDo,CDMA,GSM/WCDMA.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA =
             RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
     /**
      * Preferred network mode is TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA =
             RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
 
@@ -9416,8 +9565,10 @@
 
     /**
      * Preferred network mode is NR 5G, LTE, CDMA and EvDo.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final int NETWORK_MODE_NR_LTE_CDMA_EVDO =
             RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO;
 
@@ -9430,8 +9581,10 @@
 
     /**
      * Preferred network mode is NR 5G, LTE, CDMA, EvDo, GSM and WCDMA.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final int NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA =
             RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA;
 
@@ -9470,8 +9623,10 @@
 
     /**
      * Preferred network mode is NR 5G, LTE, TD-SCDMA, CDMA, EVDO, GSM and WCDMA.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public static final int NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA =
             RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
 
@@ -10172,9 +10327,6 @@
      * This API will result in allowing an intersection of allowed network types for all reasons,
      * including the configuration done through other reasons.
      *
-     * If device supports satellite service, then
-     * {@link #NETWORK_TYPE_NB_IOT_NTN} is added to allowed network types for reason by default.
-     *
      * @param reason the reason the allowed network type change is taking place
      * @param allowedNetworkTypes The bitmask of allowed network type
      * @throws IllegalStateException if the Telephony process is not currently available.
@@ -10224,10 +10376,6 @@
      * <p>Requires permission: android.Manifest.READ_PRIVILEGED_PHONE_STATE or
      * that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
      *
-     * If device supports satellite service, then
-     * {@link #NETWORK_TYPE_NB_IOT_NTN} is added to allowed network types for reason by
-     * default.
-     *
      * @param reason the reason the allowed network type change is taking place
      * @return the allowed network type bitmask
      * @throws IllegalStateException    if the Telephony process is not currently available.
@@ -10294,7 +10442,7 @@
      */
     public static String convertNetworkTypeBitmaskToString(
             @NetworkTypeBitMask long networkTypeBitmask) {
-        String networkTypeName = IntStream.rangeClosed(NETWORK_TYPE_GPRS, NETWORK_TYPE_NB_IOT_NTN)
+        String networkTypeName = IntStream.rangeClosed(NETWORK_TYPE_GPRS, NETWORK_TYPE_NR)
                 .filter(x -> {
                     return (networkTypeBitmask & getBitMaskForNetworkType(x))
                             == getBitMaskForNetworkType(x);
@@ -10552,24 +10700,32 @@
     /**
      * @throws UnsupportedOperationException If the device does not have
      *          {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public String getCdmaMdn() {
+        if (Flags.cleanupCdma()) return null;
         return getCdmaMdn(getSubId());
     }
 
     /**
      * @throws UnsupportedOperationException If the device does not have
      *          {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public String getCdmaMdn(int subId) {
+        if (Flags.cleanupCdma()) return null;
         try {
             ITelephony telephony = getITelephony();
             if (telephony == null)
@@ -10585,24 +10741,32 @@
     /**
      * @throws UnsupportedOperationException If the device does not have
      *          {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public String getCdmaMin() {
+        if (Flags.cleanupCdma()) return null;
         return getCdmaMin(getSubId());
     }
 
     /**
      * @throws UnsupportedOperationException If the device does not have
      *          {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public String getCdmaMin(int subId) {
+        if (Flags.cleanupCdma()) return null;
         try {
             ITelephony telephony = getITelephony();
             if (telephony == null)
@@ -11887,12 +12051,16 @@
      *
      * @throws UnsupportedOperationException If the device does not have
      *          {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public @CdmaRoamingMode int getCdmaRoamingMode() {
+        if (Flags.cleanupCdma()) return CDMA_ROAMING_MODE_RADIO_DEFAULT;
         int mode = CDMA_ROAMING_MODE_RADIO_DEFAULT;
         try {
             ITelephony telephony = getITelephony();
@@ -11931,12 +12099,16 @@
      *
      * @throws UnsupportedOperationException If the device does not have
      *          {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public void setCdmaRoamingMode(@CdmaRoamingMode int mode) {
+        if (Flags.cleanupCdma()) return;
         if (getPhoneType() != PHONE_TYPE_CDMA) {
             throw new IllegalStateException("Phone does not support CDMA.");
         }
@@ -11954,7 +12126,10 @@
         }
     }
 
-    /** @hide */
+    /** @hide
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @Deprecated
     @IntDef(prefix = { "CDMA_SUBSCRIPTION_" }, value = {
             CDMA_SUBSCRIPTION_UNKNOWN,
             CDMA_SUBSCRIPTION_RUIM_SIM,
@@ -11965,22 +12140,31 @@
 
     /**
      * Used for CDMA subscription mode, it'll be UNKNOWN if there is no Subscription source.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SystemApi
     public static final int CDMA_SUBSCRIPTION_UNKNOWN  = -1;
 
     /**
      * Used for CDMA subscription mode: RUIM/SIM (default)
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SystemApi
     public static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0;
 
     /**
      * Used for CDMA subscription mode: NV -> non-volatile memory
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SystemApi
     public static final int CDMA_SUBSCRIPTION_NV       = 1;
 
@@ -12001,12 +12185,16 @@
      *
      * @throws UnsupportedOperationException If the device does not have
      *          {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public @CdmaSubscription int getCdmaSubscriptionMode() {
+        if (Flags.cleanupCdma()) return CDMA_SUBSCRIPTION_UNKNOWN;
         int mode = CDMA_SUBSCRIPTION_RUIM_SIM;
         try {
             ITelephony telephony = getITelephony();
@@ -12041,12 +12229,16 @@
      *
      * @throws UnsupportedOperationException If the device does not have
      *          {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public void setCdmaSubscriptionMode(@CdmaSubscription int mode) {
+        if (Flags.cleanupCdma()) return;
         if (getPhoneType() != PHONE_TYPE_CDMA) {
             throw new IllegalStateException("Phone does not support CDMA.");
         }
@@ -13766,11 +13958,15 @@
      *
      * @throws UnsupportedOperationException If the device does not have
      *          {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SystemApi
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public String getCdmaPrlVersion() {
+        if (Flags.cleanupCdma()) return null;
         return getCdmaPrlVersion(getSubId());
     }
 
@@ -13781,9 +13977,12 @@
      *
      * @param subId the subscription ID that this request applies to.
      * @return PRLVersion or null if error.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @Deprecated
     public String getCdmaPrlVersion(int subId) {
+        if (Flags.cleanupCdma()) return null;
         try {
             ITelephony service = getITelephony();
             if (service != null) {
@@ -13837,6 +14036,7 @@
      * @hide
      */
     @SystemApi
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CARRIERLOCK)
     public int setAllowedCarriers(int slotIndex, List<CarrierIdentifier> carriers) {
@@ -14924,8 +15124,7 @@
                     NETWORK_TYPE_BITMASK_LTE_CA,
                     NETWORK_TYPE_BITMASK_NR,
                     NETWORK_TYPE_BITMASK_IWLAN,
-                    NETWORK_TYPE_BITMASK_IDEN,
-                    NETWORK_TYPE_BITMASK_NB_IOT_NTN
+                    NETWORK_TYPE_BITMASK_IDEN
             })
     public @interface NetworkTypeBitMask {}
 
@@ -14948,7 +15147,10 @@
     public static final long NETWORK_TYPE_BITMASK_EDGE = (1 << (NETWORK_TYPE_EDGE -1));
     /**
      * network type bitmask indicating the support of radio tech CDMA(IS95A/IS95B).
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final long NETWORK_TYPE_BITMASK_CDMA = (1 << (NETWORK_TYPE_CDMA -1));
     /**
      * network type bitmask indicating the support of radio tech 1xRTT.
@@ -14970,7 +15172,10 @@
     public static final long NETWORK_TYPE_BITMASK_EVDO_B = (1 << (NETWORK_TYPE_EVDO_B -1));
     /**
      * network type bitmask indicating the support of radio tech EHRPD.
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final long NETWORK_TYPE_BITMASK_EHRPD = (1 << (NETWORK_TYPE_EHRPD -1));
     /**
      * network type bitmask indicating the support of radio tech HSUPA.
@@ -15026,12 +15231,6 @@
      */
     public static final long NETWORK_TYPE_BITMASK_IWLAN = (1 << (NETWORK_TYPE_IWLAN -1));
 
-    /**
-     * network type bitmask indicating the support of readio tech NB IOT NTN.
-     */
-    @FlaggedApi(Flags.FLAG_SATELLITE_SYSTEM_APIS)
-    public static final long NETWORK_TYPE_BITMASK_NB_IOT_NTN = (1 << (NETWORK_TYPE_NB_IOT_NTN - 1));
-
     /** @hide */
     public static final long NETWORK_CLASS_BITMASK_2G = NETWORK_TYPE_BITMASK_GSM
                 | NETWORK_TYPE_BITMASK_GPRS
@@ -15060,9 +15259,6 @@
     public static final long NETWORK_CLASS_BITMASK_5G = NETWORK_TYPE_BITMASK_NR;
 
     /** @hide */
-    public static final long NETWORK_CLASS_BITMASK_NTN = NETWORK_TYPE_BITMASK_NB_IOT_NTN;
-
-    /** @hide */
     public static final long NETWORK_STANDARDS_FAMILY_BITMASK_3GPP = NETWORK_TYPE_BITMASK_GSM
             | NETWORK_TYPE_BITMASK_GPRS
             | NETWORK_TYPE_BITMASK_EDGE
@@ -15074,10 +15270,12 @@
             | NETWORK_TYPE_BITMASK_TD_SCDMA
             | NETWORK_TYPE_BITMASK_LTE
             | NETWORK_TYPE_BITMASK_LTE_CA
-            | NETWORK_TYPE_BITMASK_NR
-            | NETWORK_TYPE_BITMASK_NB_IOT_NTN;
+            | NETWORK_TYPE_BITMASK_NR;
 
-    /** @hide */
+    /** @hide
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @Deprecated
     public static final long NETWORK_STANDARDS_FAMILY_BITMASK_3GPP2 = NETWORK_TYPE_BITMASK_CDMA
             | NETWORK_TYPE_BITMASK_1xRTT
             | NETWORK_TYPE_BITMASK_EVDO_0
@@ -18113,7 +18311,7 @@
      */
     public static boolean isNetworkTypeValid(@NetworkType int networkType) {
         return networkType >= TelephonyManager.NETWORK_TYPE_UNKNOWN &&
-                networkType <= TelephonyManager.NETWORK_TYPE_NB_IOT_NTN;
+                networkType <= TelephonyManager.NETWORK_TYPE_NR;
     }
 
     /**
diff --git a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java
index 02429b5..8fccf65 100644
--- a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java
+++ b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java
@@ -16,12 +16,15 @@
 
 package android.telephony.cdma;
 
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.internal.telephony.flags.Flags;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -34,18 +37,36 @@
  * containing an array of these objects to update its list of cell broadcast service categories
  * to display.
  *
+ * @deprecated Legacy CDMA is unsupported.
  * {@hide}
  */
+@FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+@Deprecated
 @SystemApi
 public final class CdmaSmsCbProgramData implements Parcelable {
 
-    /** Delete the specified service category from the list of enabled categories. */
+    /**
+     * Delete the specified service category from the list of enabled categories.
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int OPERATION_DELETE_CATEGORY   = 0;
 
-    /** Add the specified service category to the list of enabled categories. */
+    /**
+     * Add the specified service category to the list of enabled categories.
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int OPERATION_ADD_CATEGORY      = 1;
 
-    /** Clear all service categories from the list of enabled categories. */
+    /**
+     * Clear all service categories from the list of enabled categories.
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int OPERATION_CLEAR_CATEGORIES  = 2;
 
     /** @hide */
@@ -59,23 +80,53 @@
     public @interface Operation {}
 
     // CMAS alert service category assignments, see 3GPP2 C.R1001 table 9.3.3-1
-    /** Indicates a presidential-level alert */
+    /**
+     * Indicates a presidential-level alert
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT  = 0x1000;
 
-    /** Indicates an extreme threat to life and property */
+    /**
+     * Indicates an extreme threat to life and property
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CATEGORY_CMAS_EXTREME_THREAT            = 0x1001;
 
-    /** Indicates an severe threat to life and property */
+    /**
+     * Indicates an severe threat to life and property
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CATEGORY_CMAS_SEVERE_THREAT             = 0x1002;
 
-    /** Indicates an AMBER child abduction emergency */
+    /**
+     * Indicates an AMBER child abduction emergency
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 0x1003;
 
-    /** Indicates a CMAS test message */
+    /**
+     * Indicates a CMAS test message
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CATEGORY_CMAS_TEST_MESSAGE              = 0x1004;
 
-    /** The last reserved value of a CMAS service category according to 3GPP C.R1001 table
-     * 9.3.3-1. */
+    /**
+     * The last reserved value of a CMAS service category according to 3GPP C.R1001 table
+     * 9.3.3-1.
+     * @deprecated Legacy CDMA is unsupported.
+     */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public static final int CATEGORY_CMAS_LAST_RESERVED_VALUE       = 0x10ff;
 
     /** @hide */
@@ -177,7 +228,10 @@
      *
      * @param dest  The Parcel in which the object should be written.
      * @param flags Additional flags about how the object should be written (ignored).
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mOperation);
@@ -192,7 +246,10 @@
      * Returns the service category operation, e.g. {@link #OPERATION_ADD_CATEGORY}.
      *
      * @return the service category operation
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public @Operation int getOperation() {
         return mOperation;
     }
@@ -203,7 +260,10 @@
      * 0x10FF are supported.
      *
      * @return a 16-bit CDMA service category value
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     public @Category int getCategory() {
         return mCategory;
     }
@@ -255,7 +315,11 @@
     /**
      * Describe the kinds of special objects contained in the marshalled representation.
      * @return a bitmask indicating this Parcelable contains no special objects
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @Override
     public int describeContents() {
         return 0;
@@ -263,7 +327,11 @@
 
     /**
      * Creator for unparcelling objects.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @NonNull
     public static final Parcelable.Creator<CdmaSmsCbProgramData>
             CREATOR = new Parcelable.Creator<CdmaSmsCbProgramData>() {
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index 8925a9e..76f83ee 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -18,6 +18,7 @@
 
 import android.Manifest;
 import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -37,6 +38,8 @@
 import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
 import android.util.Log;
 
+import com.android.internal.telephony.flags.Flags;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
@@ -226,8 +229,11 @@
 
     /**
      * A capability update has been requested due to moving to eHRPD.
+     * @deprecated Legacy CDMA is unsupported.
      * @hide
      */
+    @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+    @Deprecated
     @SystemApi
     public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 4;
 
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index 0f23f33..f687af6 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -3621,8 +3621,6 @@
      * @throws IllegalStateException if the Telephony process is not currently available.
      * @hide
      */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_SATELLITE_SYSTEM_APIS)
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     public void requestSatelliteDisplayName(
             @NonNull @CallbackExecutor Executor executor,
diff --git a/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java b/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java
index eaeed2a..b1a5b1b 100644
--- a/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java
+++ b/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java
@@ -17,6 +17,7 @@
 package android.telephony.satellite.stub;
 
 import android.annotation.NonNull;
+import android.hardware.radio.network.IRadioNetwork;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.telephony.IBooleanConsumer;
@@ -586,7 +587,11 @@
      *   SatelliteResult:SATELLITE_RESULT_NO_RESOURCES
      *   SatelliteResult:SATELLITE_RESULT_RADIO_NOT_AVAILABLE
      *   SatelliteResult:SATELLITE_RESULT_REQUEST_NOT_SUPPORTED
+     *
+     * @deprecated Use
+     * {@link IRadioNetwork#setSatellitePlmn(int, int, String[], String[])}.
      */
+    @Deprecated
     public void setSatellitePlmn(@NonNull int simLogicalSlotIndex,
             @NonNull List<String> carrierPlmnList, @NonNull List<String> allSatellitePlmnList,
             @NonNull IIntegerConsumer resultCallback) {
@@ -608,7 +613,11 @@
      *   SatelliteResult:SATELLITE_RESULT_MODEM_ERROR
      *   SatelliteResult:SATELLITE_RESULT_RADIO_NOT_AVAILABLE
      *   SatelliteResult:SATELLITE_RESULT_REQUEST_NOT_SUPPORTED
+     *
+     * @deprecated Use
+     * {@link IRadioNetwork#setSatelliteEnabledForCarrier(int, int, boolean)}.
      */
+    @Deprecated
     public void setSatelliteEnabledForCarrier(@NonNull int simLogicalSlotIndex,
             @NonNull boolean satelliteEnabled, @NonNull IIntegerConsumer callback) {
         // stub implementation
@@ -629,7 +638,11 @@
      *   SatelliteResult:SATELLITE_RESULT_MODEM_ERROR
      *   SatelliteResult:SATELLITE_RESULT_RADIO_NOT_AVAILABLE
      *   SatelliteResult:SATELLITE_RESULT_REQUEST_NOT_SUPPORTED
+     *
+     * @deprecated Use
+     * {@link IRadioNetwork#isSatelliteEnabledForCarrier(int, int)}.
      */
+    @Deprecated
     public void requestIsSatelliteEnabledForCarrier(@NonNull int simLogicalSlotIndex,
             @NonNull IIntegerConsumer resultCallback, @NonNull IBooleanConsumer callback) {
         // stub implementation
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index da7669f..74d9204 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -416,6 +416,8 @@
      * Returns the CDMA ERI icon index to display
      * @param callingPackage package making the call.
      * @param callingFeatureId The feature in the package.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     int getCdmaEriIconIndex(String callingPackage, String callingFeatureId);
 
@@ -424,6 +426,8 @@
      * @param subId user preferred subId.
      * @param callingPackage package making the call.
      * @param callingFeatureId The feature in the package.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
             String callingFeatureId);
@@ -434,6 +438,8 @@
      * 1 - FLASHING
      * @param callingPackage package making the call.
      * @param callingFeatureId The feature in the package.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     int getCdmaEriIconMode(String callingPackage, String callingFeatureId);
 
@@ -444,6 +450,8 @@
      * @param subId user preferred subId.
      * @param callingPackage package making the call.
      * @param callingFeatureId The feature in the package.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
             String callingFeatureId);
@@ -452,6 +460,8 @@
      * Returns the CDMA ERI text,
      * @param callingPackage package making the call.
      * @param callingFeatureId The feature in the package.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     String getCdmaEriText(String callingPackage, String callingFeatureId);
 
@@ -460,6 +470,8 @@
      * @param subId user preferred subId.
      * @param callingPackage package making the call.
      * @param callingFeatureId The feature in the package.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     String getCdmaEriTextForSubscriber(int subId, String callingPackage, String callingFeatureId);
 
@@ -779,6 +791,8 @@
      *
      * @param itemID the ID of the item to read.
      * @return the NV item as a String, or null on any failure.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     String nvReadItem(int itemID);
 
@@ -789,6 +803,8 @@
      * @param itemID the ID of the item to read.
      * @param itemValue the value to write, as a String.
      * @return true on success; false on any failure.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     boolean nvWriteItem(int itemID, String itemValue);
 
@@ -798,6 +814,8 @@
      *
      * @param preferredRoamingList byte array containing the new PRL.
      * @return true on success; false on any failure.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     boolean nvWriteCdmaPrl(in byte[] preferredRoamingList);
 
@@ -811,6 +829,8 @@
      *
      * @param slotIndex - device slot.
      * @return {@code true} on success; {@code false} on any failure.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     boolean resetModemConfig(int slotIndex);
 
@@ -1041,12 +1061,16 @@
     /**
      * Return MDN string for CDMA phone.
      * @param subId user preferred subId.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     String getCdmaMdn(int subId);
 
     /**
      * Return MIN string for CDMA phone.
      * @param subId user preferred subId.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     String getCdmaMin(int subId);
 
@@ -1495,13 +1519,14 @@
     String getEsn(int subId);
 
     /**
-    * Return the Preferred Roaming List Version
-    *
-    * Requires that the calling app has READ_PRIVILEGED_PHONE_STATE permission
-    * @param subId the subscription ID that this request applies to.
-    * @return PRLVersion or null if error.
-    * @hide
-    */
+     * Return the Preferred Roaming List Version
+     *
+     * Requires that the calling app has READ_PRIVILEGED_PHONE_STATE permission
+     * @param subId the subscription ID that this request applies to.
+     * @return PRLVersion or null if error.
+     * @hide
+     * @deprecated Legacy CDMA is unsupported.
+     */
     String getCdmaPrlVersion(int subId);
 
     /**
@@ -1804,6 +1829,8 @@
      *
      * @param the subscription id.
      * @return the roaming mode for CDMA phone.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     int getCdmaRoamingMode(int subId);
 
@@ -1814,6 +1841,8 @@
      * @param subId the subscription id.
      * @param mode the roaming mode should be set.
      * @return {@code true} if successed.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     boolean setCdmaRoamingMode(int subId, int mode);
 
@@ -1822,6 +1851,8 @@
      *
      * @param the subscription id.
      * @return the subscription mode for CDMA phone.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     int getCdmaSubscriptionMode(int subId);
 
@@ -1832,6 +1863,8 @@
      * @param subId the subscription id.
      * @param mode the subscription mode should be set.
      * @return {@code true} if successed.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     boolean setCdmaSubscriptionMode(int subId, int mode);
 
diff --git a/tests/AppJankTest/Android.bp b/tests/AppJankTest/Android.bp
index acf8dc9..c3cda6a 100644
--- a/tests/AppJankTest/Android.bp
+++ b/tests/AppJankTest/Android.bp
@@ -30,6 +30,7 @@
         "androidx.test.core",
         "platform-test-annotations",
         "flag-junit",
+        "androidx.test.uiautomator_uiautomator",
     ],
     platform_apis: true,
     test_suites: ["device-tests"],
diff --git a/tests/AppJankTest/AndroidManifest.xml b/tests/AppJankTest/AndroidManifest.xml
index abed179..861a79c 100644
--- a/tests/AppJankTest/AndroidManifest.xml
+++ b/tests/AppJankTest/AndroidManifest.xml
@@ -19,22 +19,31 @@
           package="android.app.jank.tests">
 
     <application android:appCategory="news">
-        <uses-library android:name="android.test.runner" />
-        <activity android:name=".EmptyActivity"
-                  android:label="EmptyActivity"
-                  android:exported="true">
+        <activity android:name=".JankTrackerActivity"
+                  android:exported="true"
+                  android:label="JankTrackerActivity"
+                  android:launchMode="singleTop">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <action android:name="android.intent.action.VIEW_PERMISSION_USAGE"/>
             </intent-filter>
         </activity>
+        <activity android:name=".EmptyActivity"
+                  android:exported="true"
+                  android:label="EmptyActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <action android:name="android.intent.action.VIEW_PERMISSION_USAGE"/>
+            </intent-filter>
+        </activity>
+        <uses-library android:name="android.test.runner"/>
     </application>
 
     <!--  self-instrumenting test package. -->
     <instrumentation
         android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="android.app.jank.tests"
-        android:label="Core tests of App Jank Tracking">
+        android:label="Core tests of App Jank Tracking"
+        android:targetPackage="android.app.jank.tests">
     </instrumentation>
 
 </manifest>
\ No newline at end of file
diff --git a/tests/AppJankTest/res/layout/jank_tracker_activity_layout.xml b/tests/AppJankTest/res/layout/jank_tracker_activity_layout.xml
new file mode 100644
index 0000000..65def7f
--- /dev/null
+++ b/tests/AppJankTest/res/layout/jank_tracker_activity_layout.xml
@@ -0,0 +1,47 @@
+<?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.
+  -->
+
+
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:fitsSystemWindows="true">
+
+    <LinearLayout
+        android:id="@+id/linear_layout"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+        <EditText
+            android:id="@+id/edit_text"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:inputType="textEnableTextConversionSuggestions"
+            android:text="Edit Text"/>
+        <TextView android:id="@+id/text_view"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:text="Text View"
+        />
+        <android.app.jank.tests.TestWidget
+            android:id="@+id/jank_tracker_widget"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+        />
+    </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/tests/AppJankTest/src/android/app/jank/tests/IntegrationTests.java b/tests/AppJankTest/src/android/app/jank/tests/IntegrationTests.java
new file mode 100644
index 0000000..34f0c19
--- /dev/null
+++ b/tests/AppJankTest/src/android/app/jank/tests/IntegrationTests.java
@@ -0,0 +1,215 @@
+/*
+ * 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.jank.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.app.jank.AppJankStats;
+import android.app.jank.Flags;
+import android.app.jank.JankDataProcessor;
+import android.app.jank.JankTracker;
+import android.app.jank.StateTracker;
+import android.content.Intent;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.widget.EditText;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * This file contains tests that verify the proper functionality of the Jank Tracking feature.
+ * All tests should obtain references to necessary objects through View type interfaces, rather
+ * than direct instantiation. When operating outside of a testing environment, the expected
+ * behavior is to retrieve the necessary objects using View type interfaces. This approach ensures
+ * that calls are correctly routed down to the activity level. Any modifications to the call
+ * routing should result in test failures, which might happen with direct instantiations.
+ */
+@RunWith(AndroidJUnit4.class)
+public class IntegrationTests {
+    public static final int WAIT_FOR_TIMEOUT_MS = 5000;
+
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+    private Activity mEmptyActivity;
+
+    public UiDevice mDevice;
+    private Instrumentation mInstrumentation;
+    private ActivityTestRule<JankTrackerActivity> mJankTrackerActivityRule =
+            new ActivityTestRule<>(
+                    JankTrackerActivity.class,
+                    false,
+                    false);
+
+    private ActivityTestRule<EmptyActivity> mEmptyActivityRule =
+            new ActivityTestRule<>(EmptyActivity.class, false , true);
+
+    @Before
+    public void setUp() {
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mDevice = UiDevice.getInstance(mInstrumentation);
+    }
+
+
+    /**
+     * Get a JankTracker object from a view and confirm it's not null.
+     */
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
+    public void getJankTacker_confirmNotNull() {
+        Activity jankTrackerActivity = mJankTrackerActivityRule.launchActivity(null);
+        EditText editText = jankTrackerActivity.findViewById(R.id.edit_text);
+
+        mDevice.wait(Until.findObject(By.text("Edit Text")), WAIT_FOR_TIMEOUT_MS);
+
+        JankTracker jankTracker = editText.getJankTracker();
+        assertTrue(jankTracker != null);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
+    public void reportJankStats_confirmPendingStatsIncreases() {
+        Activity jankTrackerActivity = mJankTrackerActivityRule.launchActivity(null);
+        EditText editText = jankTrackerActivity.findViewById(R.id.edit_text);
+        JankTracker jankTracker = editText.getJankTracker();
+
+        HashMap<String, JankDataProcessor.PendingJankStat> pendingStats =
+                jankTracker.getPendingJankStats();
+        assertEquals(0, pendingStats.size());
+
+        editText.reportAppJankStats(JankUtils.getAppJankStats());
+
+        // reportAppJankStats performs the work on a background thread, check periodically to see
+        // if the work is complete.
+        for (int i = 0; i < 10; i++) {
+            try {
+                Thread.sleep(100);
+                if (jankTracker.getPendingJankStats().size() > 0) {
+                    break;
+                }
+            } catch (InterruptedException exception) {
+                //do nothing and continue
+            }
+        }
+
+        pendingStats = jankTracker.getPendingJankStats();
+
+        assertEquals(1, pendingStats.size());
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
+    public void simulateWidgetStateChanges_confirmStateChangesAreTracked() {
+        JankTrackerActivity jankTrackerActivity =
+                mJankTrackerActivityRule.launchActivity(null);
+        TestWidget testWidget = jankTrackerActivity.findViewById(R.id.jank_tracker_widget);
+        JankTracker jankTracker = testWidget.getJankTracker();
+        jankTracker.forceListenerRegistration();
+
+        ArrayList<StateTracker.StateData> uiStates = new ArrayList<>();
+        // Get the current UI states, at this point only the activity name should be in the UI
+        // states list.
+        jankTracker.getAllUiStates(uiStates);
+
+        assertEquals(1, uiStates.size());
+
+        // This should add a UI state to be tracked.
+        testWidget.simulateAnimationStarting();
+        uiStates.clear();
+        jankTracker.getAllUiStates(uiStates);
+
+        assertEquals(2, uiStates.size());
+
+        // Stop the animation
+        testWidget.simulateAnimationEnding();
+        uiStates.clear();
+        jankTracker.getAllUiStates(uiStates);
+
+        assertEquals(2, uiStates.size());
+
+        // Confirm the Animation state has a VsyncIdEnd that is not default, indicating the end
+        // of that state.
+        for (int i = 0; i < uiStates.size(); i++) {
+            StateTracker.StateData stateData = uiStates.get(i);
+            if (stateData.mWidgetCategory.equals(AppJankStats.ANIMATION)) {
+                assertNotEquals(Long.MAX_VALUE, stateData.mVsyncIdEnd);
+            }
+        }
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
+    public void jankTrackingPaused_whenActivityNoLongerVisible() {
+        JankTrackerActivity jankTrackerActivity =
+                mJankTrackerActivityRule.launchActivity(null);
+        TestWidget testWidget = jankTrackerActivity.findViewById(R.id.jank_tracker_widget);
+        JankTracker jankTracker = testWidget.getJankTracker();
+        jankTracker.forceListenerRegistration();
+
+        assertTrue(jankTracker.shouldTrack());
+
+        // Send jankTrackerActivity to the background
+        mDevice.pressHome();
+        mDevice.waitForIdle(WAIT_FOR_TIMEOUT_MS);
+
+        assertFalse(jankTracker.shouldTrack());
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
+    public void jankTrackingResumed_whenActivityBecomesVisibleAgain() {
+        mEmptyActivityRule.launchActivity(null);
+        mEmptyActivity = mEmptyActivityRule.getActivity();
+        JankTrackerActivity jankTrackerActivity =
+                mJankTrackerActivityRule.launchActivity(null);
+        TestWidget testWidget = jankTrackerActivity.findViewById(R.id.jank_tracker_widget);
+        JankTracker jankTracker = testWidget.getJankTracker();
+        jankTracker.forceListenerRegistration();
+
+        // Send jankTrackerActivity to the background
+        mDevice.pressHome();
+        mDevice.waitForIdle(WAIT_FOR_TIMEOUT_MS);
+
+        assertFalse(jankTracker.shouldTrack());
+
+        Intent resumeJankTracker = new Intent(mInstrumentation.getContext(),
+                JankTrackerActivity.class);
+        resumeJankTracker.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
+        mEmptyActivity.startActivity(resumeJankTracker);
+        mDevice.wait(Until.findObject(By.text("Edit Text")), WAIT_FOR_TIMEOUT_MS);
+
+        assertTrue(jankTracker.shouldTrack());
+    }
+}
diff --git a/tests/AppJankTest/src/android/app/jank/tests/JankDataProcessorTest.java b/tests/AppJankTest/src/android/app/jank/tests/JankDataProcessorTest.java
index 4d495ad..30c568b 100644
--- a/tests/AppJankTest/src/android/app/jank/tests/JankDataProcessorTest.java
+++ b/tests/AppJankTest/src/android/app/jank/tests/JankDataProcessorTest.java
@@ -20,7 +20,6 @@
 
 import android.app.jank.AppJankStats;
 import android.app.jank.Flags;
-import android.app.jank.FrameOverrunHistogram;
 import android.app.jank.JankDataProcessor;
 import android.app.jank.StateTracker;
 import android.platform.test.annotations.RequiresFlagsEnabled;
@@ -165,7 +164,7 @@
 
         assertEquals(pendingStats.size(), 0);
 
-        AppJankStats jankStats = getAppJankStats();
+        AppJankStats jankStats = JankUtils.getAppJankStats();
         mJankDataProcessor.mergeJankStats(jankStats, sActivityName);
 
         pendingStats = mJankDataProcessor.getPendingJankStats();
@@ -182,14 +181,14 @@
     @Test
     @RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
     public void mergeAppJankStats_confirmStatsWithMatchingStatesAreCombinedIntoOnePendingStat() {
-        AppJankStats jankStats = getAppJankStats();
+        AppJankStats jankStats = JankUtils.getAppJankStats();
         mJankDataProcessor.mergeJankStats(jankStats, sActivityName);
 
         HashMap<String, JankDataProcessor.PendingJankStat> pendingStats =
                 mJankDataProcessor.getPendingJankStats();
         assertEquals(pendingStats.size(), 1);
 
-        AppJankStats secondJankStat = getAppJankStats();
+        AppJankStats secondJankStat = JankUtils.getAppJankStats();
         mJankDataProcessor.mergeJankStats(secondJankStat, sActivityName);
 
         pendingStats = mJankDataProcessor.getPendingJankStats();
@@ -200,7 +199,7 @@
     @Test
     @RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
     public void mergeAppJankStats_whenStatsWithMatchingStatesMerge_confirmFrameCountsAdded() {
-        AppJankStats jankStats = getAppJankStats();
+        AppJankStats jankStats = JankUtils.getAppJankStats();
         mJankDataProcessor.mergeJankStats(jankStats, sActivityName);
         mJankDataProcessor.mergeJankStats(jankStats, sActivityName);
 
@@ -345,27 +344,4 @@
 
         return mockData;
     }
-
-    private AppJankStats getAppJankStats() {
-        AppJankStats jankStats = new AppJankStats(
-                /*App Uid*/APP_ID,
-                /*Widget Id*/"test widget id",
-                /*Widget Category*/AppJankStats.SCROLL,
-                /*Widget State*/AppJankStats.SCROLLING,
-                /*Total Frames*/100,
-                /*Janky Frames*/25,
-                getOverrunHistogram()
-        );
-        return jankStats;
-    }
-
-    private FrameOverrunHistogram getOverrunHistogram() {
-        FrameOverrunHistogram overrunHistogram = new FrameOverrunHistogram();
-        overrunHistogram.addFrameOverrunMillis(-2);
-        overrunHistogram.addFrameOverrunMillis(1);
-        overrunHistogram.addFrameOverrunMillis(5);
-        overrunHistogram.addFrameOverrunMillis(25);
-        return overrunHistogram;
-    }
-
 }
diff --git a/tests/AppJankTest/src/android/app/jank/tests/JankTrackerActivity.java b/tests/AppJankTest/src/android/app/jank/tests/JankTrackerActivity.java
new file mode 100644
index 0000000..80ab6ad3
--- /dev/null
+++ b/tests/AppJankTest/src/android/app/jank/tests/JankTrackerActivity.java
@@ -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 android.app.jank.tests;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+public class JankTrackerActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.jank_tracker_activity_layout);
+    }
+}
+
+
diff --git a/tests/AppJankTest/src/android/app/jank/tests/JankUtils.java b/tests/AppJankTest/src/android/app/jank/tests/JankUtils.java
new file mode 100644
index 0000000..0b4d97e
--- /dev/null
+++ b/tests/AppJankTest/src/android/app/jank/tests/JankUtils.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 android.app.jank.tests;
+
+import android.app.jank.AppJankStats;
+import android.app.jank.FrameOverrunHistogram;
+
+public class JankUtils {
+    private static final int APP_ID = 25;
+
+    /**
+     * Returns a mock AppJankStats object to be used in tests.
+     */
+    public static AppJankStats getAppJankStats() {
+        AppJankStats jankStats = new AppJankStats(
+                /*App Uid*/APP_ID,
+                /*Widget Id*/"test widget id",
+                /*Widget Category*/AppJankStats.SCROLL,
+                /*Widget State*/AppJankStats.SCROLLING,
+                /*Total Frames*/100,
+                /*Janky Frames*/25,
+                getOverrunHistogram()
+        );
+        return jankStats;
+    }
+
+    /**
+     * Returns a mock histogram to be used with an AppJankStats object.
+     */
+    public static FrameOverrunHistogram getOverrunHistogram() {
+        FrameOverrunHistogram overrunHistogram = new FrameOverrunHistogram();
+        overrunHistogram.addFrameOverrunMillis(-2);
+        overrunHistogram.addFrameOverrunMillis(1);
+        overrunHistogram.addFrameOverrunMillis(5);
+        overrunHistogram.addFrameOverrunMillis(25);
+        return overrunHistogram;
+    }
+}
diff --git a/tests/AppJankTest/src/android/app/jank/tests/TestWidget.java b/tests/AppJankTest/src/android/app/jank/tests/TestWidget.java
new file mode 100644
index 0000000..5fff460
--- /dev/null
+++ b/tests/AppJankTest/src/android/app/jank/tests/TestWidget.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.jank.tests;
+
+import android.app.jank.AppJankStats;
+import android.app.jank.JankTracker;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+
+public class TestWidget extends View {
+
+    private JankTracker mJankTracker;
+
+    /**
+     * Create JankTrackerView
+     */
+    public TestWidget(Context context) {
+        super(context);
+    }
+
+    /**
+     * Create JankTrackerView, needed by system when inflating views defined in a layout file.
+     */
+    public TestWidget(Context context, AttributeSet attributeSet) {
+        super(context, attributeSet);
+    }
+
+    /**
+     * Mock starting an animation.
+     */
+    public void simulateAnimationStarting() {
+        if (jankTrackerCreated()) {
+            mJankTracker.addUiState(AppJankStats.ANIMATION,
+                    Integer.toString(this.getId()), AppJankStats.ANIMATING);
+        }
+    }
+
+    /**
+     * Mock ending an animation.
+     */
+    public void simulateAnimationEnding() {
+        if (jankTrackerCreated()) {
+            mJankTracker.removeUiState(AppJankStats.ANIMATION,
+                    Integer.toString(this.getId()), AppJankStats.ANIMATING);
+        }
+    }
+
+    private boolean jankTrackerCreated() {
+        if (mJankTracker == null) {
+            mJankTracker = getJankTracker();
+        }
+        return mJankTracker != null;
+    }
+}
diff --git a/tests/Input/res/xml/bookmarks.xml b/tests/Input/res/xml/bookmarks.xml
index a4c898d..68ec123 100644
--- a/tests/Input/res/xml/bookmarks.xml
+++ b/tests/Input/res/xml/bookmarks.xml
@@ -23,7 +23,7 @@
         androidprv:modifierState="META" />
     <bookmark
         category="android.intent.category.APP_CONTACTS"
-        androidprv:keycode="KEYCODE_C"
+        androidprv:keycode="KEYCODE_P"
         androidprv:modifierState="META" />
     <bookmark
         category="android.intent.category.APP_EMAIL"
@@ -31,21 +31,13 @@
         androidprv:modifierState="META" />
     <bookmark
         category="android.intent.category.APP_CALENDAR"
-        androidprv:keycode="KEYCODE_K"
+        androidprv:keycode="KEYCODE_C"
         androidprv:modifierState="META" />
     <bookmark
         category="android.intent.category.APP_MAPS"
         androidprv:keycode="KEYCODE_M"
         androidprv:modifierState="META" />
     <bookmark
-        category="android.intent.category.APP_MUSIC"
-        androidprv:keycode="KEYCODE_P"
-        androidprv:modifierState="META" />
-    <bookmark
-        role="android.app.role.SMS"
-        androidprv:keycode="KEYCODE_S"
-        androidprv:modifierState="META" />
-    <bookmark
         category="android.intent.category.APP_CALCULATOR"
         androidprv:keycode="KEYCODE_U"
         androidprv:modifierState="META" />
@@ -57,7 +49,7 @@
 
     <bookmark
         category="android.intent.category.APP_CONTACTS"
-        androidprv:keycode="KEYCODE_C"
+        androidprv:keycode="KEYCODE_P"
         shift="true" />
 
     <bookmark
@@ -65,4 +57,4 @@
         class="com.test.BookmarkTest"
         androidprv:keycode="KEYCODE_J"
         shift="true" />
-</bookmarks>
\ No newline at end of file
+</bookmarks>
diff --git a/tests/Input/res/xml/bookmarks_legacy.xml b/tests/Input/res/xml/bookmarks_legacy.xml
index 8bacf49..78cc48b 100644
--- a/tests/Input/res/xml/bookmarks_legacy.xml
+++ b/tests/Input/res/xml/bookmarks_legacy.xml
@@ -22,23 +22,17 @@
         shortcut="b" />
     <bookmark
         category="android.intent.category.APP_CONTACTS"
-        shortcut="c" />
+        shortcut="p" />
     <bookmark
         category="android.intent.category.APP_EMAIL"
         shortcut="e" />
     <bookmark
         category="android.intent.category.APP_CALENDAR"
-        shortcut="k" />
+        shortcut="c" />
     <bookmark
         category="android.intent.category.APP_MAPS"
         shortcut="m" />
     <bookmark
-        category="android.intent.category.APP_MUSIC"
-        shortcut="p" />
-    <bookmark
-        role="android.app.role.SMS"
-        shortcut="s" />
-    <bookmark
         category="android.intent.category.APP_CALCULATOR"
         shortcut="u" />
 
@@ -49,7 +43,7 @@
 
     <bookmark
         category="android.intent.category.APP_CONTACTS"
-        shortcut="c"
+        shortcut="p"
         shift="true" />
 
     <bookmark
@@ -57,4 +51,4 @@
         class="com.test.BookmarkTest"
         shortcut="j"
         shift="true" />
-</bookmarks>
\ No newline at end of file
+</bookmarks>
diff --git a/tests/Input/src/com/android/server/input/InputManagerServiceTests.kt b/tests/Input/src/com/android/server/input/InputManagerServiceTests.kt
index 43844f6..aea75d8 100644
--- a/tests/Input/src/com/android/server/input/InputManagerServiceTests.kt
+++ b/tests/Input/src/com/android/server/input/InputManagerServiceTests.kt
@@ -28,10 +28,11 @@
 import android.hardware.display.VirtualDisplay
 import android.hardware.input.InputManager
 import android.hardware.input.InputManagerGlobal
+import android.hardware.input.InputSettings
+import android.hardware.input.KeyGestureEvent
 import android.os.InputEventInjectionSync
 import android.os.SystemClock
 import android.os.test.TestLooper
-import android.platform.test.annotations.EnableFlags
 import android.platform.test.annotations.Presubmit
 import android.platform.test.flag.junit.SetFlagsRule
 import android.provider.Settings
@@ -99,6 +100,7 @@
             .mockStatic(LocalServices::class.java)
             .mockStatic(PermissionChecker::class.java)
             .mockStatic(KeyCharacterMap::class.java)
+            .mockStatic(InputSettings::class.java)
             .build()!!
 
     @get:Rule
@@ -481,32 +483,102 @@
     }
 
     @Test
-    @EnableFlags(com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER)
     fun handleKeyGestures_keyboardBacklight() {
-        service.systemRunning()
-
-        val backlightDownEvent = createKeyEvent(KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_DOWN)
-        service.interceptKeyBeforeDispatching(null, backlightDownEvent, /* policyFlags = */0)
+        val backlightDownEvent =
+            KeyGestureEvent.Builder()
+                .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN)
+                .setAction(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
+                .build()
+        service.handleKeyGestureEvent(backlightDownEvent)
         verify(kbdController).decrementKeyboardBacklight(anyInt())
 
-        val backlightUpEvent = createKeyEvent(KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_UP)
-        service.interceptKeyBeforeDispatching(null, backlightUpEvent, /* policyFlags = */0)
+        val backlightUpEvent =
+            KeyGestureEvent.Builder()
+                .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP)
+                .setAction(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
+                .build()
+        service.handleKeyGestureEvent(backlightUpEvent)
         verify(kbdController).incrementKeyboardBacklight(anyInt())
     }
 
     @Test
-    @EnableFlags(com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER)
-    fun handleKeyGestures_toggleCapsLock() {
-        service.systemRunning()
+    fun handleKeyGestures_a11yBounceKeysShortcut() {
+        ExtendedMockito.doReturn(true).`when` {
+            InputSettings.isAccessibilityBounceKeysFeatureEnabled()
+        }
+        val toggleBounceKeysEvent =
+            KeyGestureEvent.Builder()
+                .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_BOUNCE_KEYS)
+                .setAction(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
+                .build()
+        service.handleKeyGestureEvent(toggleBounceKeysEvent)
+        ExtendedMockito.verify {
+            InputSettings.setAccessibilityBounceKeysThreshold(
+                any(),
+                eq(InputSettings.DEFAULT_BOUNCE_KEYS_THRESHOLD_MILLIS)
+            )
+        }
+    }
 
-        val metaDownEvent = createKeyEvent(KeyEvent.KEYCODE_META_LEFT)
-        service.interceptKeyBeforeDispatching(null, metaDownEvent, /* policyFlags = */0)
-        val altDownEvent =
-            createKeyEvent(KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.META_META_ON, KeyEvent.ACTION_DOWN)
-        service.interceptKeyBeforeDispatching(null, altDownEvent, /* policyFlags = */0)
-        val altUpEvent =
-            createKeyEvent(KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.META_META_ON, KeyEvent.ACTION_UP)
-        service.interceptKeyBeforeDispatching(null, altUpEvent, /* policyFlags = */0)
+    @Test
+    fun handleKeyGestures_a11yMouseKeysShortcut() {
+        ExtendedMockito.doReturn(true).`when` {
+            InputSettings.isAccessibilityMouseKeysFeatureFlagEnabled()
+        }
+        val toggleMouseKeysEvent =
+            KeyGestureEvent.Builder()
+                .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS)
+                .setAction(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
+                .build()
+        service.handleKeyGestureEvent(toggleMouseKeysEvent)
+        ExtendedMockito.verify {
+            InputSettings.setAccessibilityMouseKeysEnabled(any(), eq(true))
+        }
+    }
+
+    @Test
+    fun handleKeyGestures_a11yStickyKeysShortcut() {
+        ExtendedMockito.doReturn(true).`when` {
+            InputSettings.isAccessibilityStickyKeysFeatureEnabled()
+        }
+        val toggleStickyKeysEvent =
+            KeyGestureEvent.Builder()
+                .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_STICKY_KEYS)
+                .setAction(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
+                .build()
+        service.handleKeyGestureEvent(toggleStickyKeysEvent)
+        ExtendedMockito.verify {
+            InputSettings.setAccessibilityStickyKeysEnabled(any(), eq(true))
+        }
+    }
+
+    @Test
+    fun handleKeyGestures_a11ySlowKeysShortcut() {
+        ExtendedMockito.doReturn(true).`when` {
+            InputSettings.isAccessibilitySlowKeysFeatureFlagEnabled()
+        }
+        val toggleSlowKeysEvent =
+            KeyGestureEvent.Builder()
+                .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS)
+                .setAction(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
+                .build()
+        service.handleKeyGestureEvent(toggleSlowKeysEvent)
+        ExtendedMockito.verify {
+            InputSettings.setAccessibilitySlowKeysThreshold(
+                any(),
+                eq(InputSettings.DEFAULT_SLOW_KEYS_THRESHOLD_MILLIS)
+            )
+        }
+    }
+
+    @Test
+    fun handleKeyGestures_toggleCapsLock() {
+        val toggleCapsLockEvent =
+            KeyGestureEvent.Builder()
+                .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK)
+                .setAction(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
+                .build()
+        service.handleKeyGestureEvent(toggleCapsLockEvent)
 
         verify(native).toggleCapsLock(anyInt())
     }
@@ -545,25 +617,6 @@
         )
         whenever(windowManagerInternal.getKeyInterceptionInfoFromToken(any())).thenReturn(info)
     }
-
-    private fun createKeyEvent(
-        keycode: Int,
-        modifierState: Int = 0,
-        action: Int = KeyEvent.ACTION_DOWN
-    ): KeyEvent {
-        return KeyEvent(
-            /* downTime = */0,
-            /* eventTime = */0,
-            action,
-            keycode,
-            /* repeat = */0,
-            modifierState,
-            KeyCharacterMap.VIRTUAL_KEYBOARD,
-            /* scancode = */0,
-            /* flags = */0,
-            InputDevice.SOURCE_KEYBOARD
-        )
-    }
 }
 
 private fun <T> whenever(methodCall: T): OngoingStubbing<T> = `when`(methodCall)
diff --git a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
index c6d2819..fafb0e0 100644
--- a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
@@ -575,9 +575,9 @@
             ),
             TestData(
                 "META + C -> Launch Default Contacts",
-                intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_C),
+                intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_P),
                 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
-                intArrayOf(KeyEvent.KEYCODE_C),
+                intArrayOf(KeyEvent.KEYCODE_P),
                 KeyEvent.META_META_ON,
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
                 AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_CONTACTS)
@@ -593,9 +593,9 @@
             ),
             TestData(
                 "META + K -> Launch Default Calendar",
-                intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_K),
+                intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_C),
                 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
-                intArrayOf(KeyEvent.KEYCODE_K),
+                intArrayOf(KeyEvent.KEYCODE_C),
                 KeyEvent.META_META_ON,
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
                 AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_CALENDAR)
@@ -610,24 +610,6 @@
                 AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_MAPS)
             ),
             TestData(
-                "META + P -> Launch Default Music",
-                intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_P),
-                KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
-                intArrayOf(KeyEvent.KEYCODE_P),
-                KeyEvent.META_META_ON,
-                intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
-                AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_MUSIC)
-            ),
-            TestData(
-                "META + S -> Launch Default SMS",
-                intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_S),
-                KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
-                intArrayOf(KeyEvent.KEYCODE_S),
-                KeyEvent.META_META_ON,
-                intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
-                AppLaunchData.createLaunchDataForRole(RoleManager.ROLE_SMS)
-            ),
-            TestData(
                 "META + U -> Launch Default Calculator",
                 intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_U),
                 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
@@ -872,10 +854,10 @@
                 AppLaunchData.createLaunchDataForRole(RoleManager.ROLE_BROWSER)
             ),
             TestData(
-                "META + C -> Launch Default Contacts",
-                intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_C),
+                "META + P -> Launch Default Contacts",
+                intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_P),
                 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
-                intArrayOf(KeyEvent.KEYCODE_C),
+                intArrayOf(KeyEvent.KEYCODE_P),
                 KeyEvent.META_META_ON,
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
                 AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_CONTACTS)
@@ -890,10 +872,10 @@
                 AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_EMAIL)
             ),
             TestData(
-                "META + K -> Launch Default Calendar",
-                intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_K),
+                "META + C -> Launch Default Calendar",
+                intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_C),
                 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
-                intArrayOf(KeyEvent.KEYCODE_K),
+                intArrayOf(KeyEvent.KEYCODE_C),
                 KeyEvent.META_META_ON,
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
                 AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_CALENDAR)
@@ -908,24 +890,6 @@
                 AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_MAPS)
             ),
             TestData(
-                "META + P -> Launch Default Music",
-                intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_P),
-                KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
-                intArrayOf(KeyEvent.KEYCODE_P),
-                KeyEvent.META_META_ON,
-                intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
-                AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_MUSIC)
-            ),
-            TestData(
-                "META + S -> Launch Default SMS",
-                intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_S),
-                KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
-                intArrayOf(KeyEvent.KEYCODE_S),
-                KeyEvent.META_META_ON,
-                intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
-                AppLaunchData.createLaunchDataForRole(RoleManager.ROLE_SMS)
-            ),
-            TestData(
                 "META + U -> Launch Default Calculator",
                 intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_U),
                 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
@@ -948,14 +912,14 @@
                 AppLaunchData.createLaunchDataForRole(RoleManager.ROLE_BROWSER)
             ),
             TestData(
-                "META + SHIFT + C -> Launch Default Contacts",
+                "META + SHIFT + P -> Launch Default Contacts",
                 intArrayOf(
                     KeyEvent.KEYCODE_META_LEFT,
                     KeyEvent.KEYCODE_SHIFT_LEFT,
-                    KeyEvent.KEYCODE_C
+                    KeyEvent.KEYCODE_P
                 ),
                 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
-                intArrayOf(KeyEvent.KEYCODE_C),
+                intArrayOf(KeyEvent.KEYCODE_P),
                 KeyEvent.META_META_ON or KeyEvent.META_SHIFT_ON,
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
                 AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_CONTACTS)
@@ -1732,4 +1696,4 @@
             return true
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/Input/src/com/android/test/input/KeyCharacterMapTest.kt b/tests/Input/src/com/android/test/input/KeyCharacterMapTest.kt
new file mode 100644
index 0000000..2818379
--- /dev/null
+++ b/tests/Input/src/com/android/test/input/KeyCharacterMapTest.kt
@@ -0,0 +1,55 @@
+/*
+ * 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 com.android.test.input
+
+import android.view.KeyCharacterMap
+import android.view.KeyEvent
+
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+/**
+ * Tests for {@link KeyCharacterMap}.
+ *
+ * <p>Build/Install/Run:
+ * atest KeyCharacterMapTest
+ *
+ */
+class KeyCharacterMapTest {
+    @Test
+    fun testGetFallback() {
+        // Based off of VIRTUAL kcm fallbacks.
+        val keyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD)
+
+        // One modifier fallback.
+        assertEquals(
+            keyCharacterMap.getFallbackAction(KeyEvent.KEYCODE_SPACE,
+                KeyEvent.META_CTRL_ON).keyCode,
+            KeyEvent.KEYCODE_LANGUAGE_SWITCH)
+
+        // Multiple modifier fallback.
+        assertEquals(
+            keyCharacterMap.getFallbackAction(KeyEvent.KEYCODE_DEL,
+                KeyEvent.META_CTRL_ON or KeyEvent.META_ALT_ON).keyCode,
+            KeyEvent.KEYCODE_BACK)
+
+        // No default button, fallback only.
+        assertEquals(
+            keyCharacterMap.getFallbackAction(KeyEvent.KEYCODE_BUTTON_A, 0).keyCode,
+            KeyEvent.KEYCODE_DPAD_CENTER)
+    }
+}
diff --git a/tests/PackageWatchdog/src/com/android/server/ExplicitHealthCheckServiceTest.java b/tests/PackageWatchdog/src/com/android/server/ExplicitHealthCheckServiceTest.java
index cd2ab86..055e159 100644
--- a/tests/PackageWatchdog/src/com/android/server/ExplicitHealthCheckServiceTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/ExplicitHealthCheckServiceTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server;
 
+import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_HEALTH_CHECK_PASSED_PACKAGE;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.spy;
@@ -35,8 +37,6 @@
 
     private ExplicitHealthCheckService mExplicitHealthCheckService;
     private static final String PACKAGE_NAME = "com.test.package";
-    private static final String EXTRA_HEALTH_CHECK_PASSED_PACKAGE =
-            "android.service.watchdog.extra.health_check_passed_package";
 
     @Before
     public void setup() throws Exception {
@@ -52,7 +52,7 @@
         IBinder binder = mExplicitHealthCheckService.onBind(new Intent());
         CountDownLatch countDownLatch = new CountDownLatch(1);
         RemoteCallback callback = new RemoteCallback(result -> {
-            assertThat(result.get(EXTRA_HEALTH_CHECK_PASSED_PACKAGE))
+            assertThat(result.getString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE))
                     .isEqualTo(PACKAGE_NAME);
             countDownLatch.countDown();
         });
diff --git a/tests/broadcasts/unit/src/android/app/BroadcastStickyCacheTest.java b/tests/broadcasts/unit/src/android/app/BroadcastStickyCacheTest.java
index ad032fb..15a580c 100644
--- a/tests/broadcasts/unit/src/android/app/BroadcastStickyCacheTest.java
+++ b/tests/broadcasts/unit/src/android/app/BroadcastStickyCacheTest.java
@@ -20,6 +20,7 @@
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
 
 import static org.junit.Assert.assertFalse;
 import static org.mockito.ArgumentMatchers.any;
@@ -186,6 +187,22 @@
     }
 
     @Test
+    public void getIntent_queryActionTwiceWithNullResult_verifyRegisterReceiverIsCalledOnce()
+            throws RemoteException {
+        setActivityManagerMock(null);
+        final Intent intent = queryIntent(new IntentFilter(Intent.ACTION_DEVICE_STORAGE_FULL));
+        final Intent cachedIntent = queryIntent(
+                new IntentFilter(Intent.ACTION_DEVICE_STORAGE_FULL));
+
+        assertNull(intent);
+        assertNull(cachedIntent);
+
+        verify(mActivityManagerMock, times(1)).registerReceiverWithFeature(
+                eq(mIApplicationThreadMock), anyString(), anyString(), anyString(), any(),
+                any(), anyString(), anyInt(), anyInt());
+    }
+
+    @Test
     public void getIntent_querySameActionWithDifferentFilter_verifyRegisterReceiverCalledTwice()
             throws RemoteException {
         setActivityManagerMock(Intent.ACTION_DEVICE_STORAGE_LOW);
@@ -226,6 +243,6 @@
         when(ActivityManager.getService()).thenReturn(mActivityManagerMock);
         when(mActivityManagerMock.registerReceiverWithFeature(any(), anyString(),
                 anyString(), anyString(), any(), any(), anyString(), anyInt(),
-                anyInt())).thenReturn(new Intent(action));
+                anyInt())).thenReturn(action != null ? new Intent(action) : null);
     }
 }
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt
index c3595b7..272d8bb 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt
@@ -119,7 +119,8 @@
                         }
 
                         logCallVisitor?.processCall(call, messageString, getLevelForMethodName(
-                            call.name.toString(), call, context), groupMap.getValue(groupName))
+                            call.name.toString(), call, context), groupMap.getValue(groupName),
+                            context.lineNumber)
                     } else if (call.name.id == "init") {
                         // No processing
                     } else {
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallVisitor.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallVisitor.kt
index 8cd927a..216241a 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallVisitor.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallVisitor.kt
@@ -20,5 +20,11 @@
 import com.github.javaparser.ast.expr.MethodCallExpr
 
 interface ProtoLogCallVisitor {
-    fun processCall(call: MethodCallExpr, messageString: String, level: LogLevel, group: LogGroup)
+    fun processCall(
+        call: MethodCallExpr,
+        messageString: String,
+        level: LogLevel,
+        group: LogGroup,
+        lineNumber: Int
+    )
 }
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
index 9222ff4..d8a2954 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
@@ -69,7 +69,8 @@
         val messageString: String,
         val logLevel: LogLevel,
         val logGroup: LogGroup,
-        val position: String
+        val position: String,
+        val lineNumber: Int,
     )
 
     private fun showHelpAndExit() {
@@ -435,9 +436,10 @@
                 call: MethodCallExpr,
                 messageString: String,
                 level: LogLevel,
-                group: LogGroup
+                group: LogGroup,
+                lineNumber: Int,
             ) {
-                val logCall = LogCall(messageString, level, group, packagePath)
+                val logCall = LogCall(messageString, level, group, packagePath, lineNumber)
                 calls.add(logCall)
             }
         }
diff --git a/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt b/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
index c478f58..76df067 100644
--- a/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
@@ -91,7 +91,8 @@
             call: MethodCallExpr,
             messageString: String,
             level: LogLevel,
-            group: LogGroup
+            group: LogGroup,
+            lineNumber: Int,
         ) {
             validateCall(call)
             val processedCallStatement =
diff --git a/tools/protologtool/src/com/android/protolog/tool/ViewerConfigProtoBuilder.kt b/tools/protologtool/src/com/android/protolog/tool/ViewerConfigProtoBuilder.kt
index de85411..5af2d94 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ViewerConfigProtoBuilder.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ViewerConfigProtoBuilder.kt
@@ -59,7 +59,7 @@
                         .setLevel(
                             ProtoLogLevel.forNumber(log.logLevel.id))
                         .setGroupId(groupId)
-                        .setLocation(log.position)
+                        .setLocation("${log.position}:${log.lineNumber}")
             )
         }
 
diff --git a/tools/protologtool/tests/com/android/protolog/tool/ProtoLogCallProcessorImplTest.kt b/tools/protologtool/tests/com/android/protolog/tool/ProtoLogCallProcessorImplTest.kt
index 5e50f71..004d97b 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/ProtoLogCallProcessorImplTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/ProtoLogCallProcessorImplTest.kt
@@ -42,7 +42,8 @@
             call: MethodCallExpr,
             messageString: String,
             level: LogLevel,
-            group: LogGroup
+            group: LogGroup,
+            lineNumber: Int,
         ) {
             calls.add(LogCall(call, messageString, level, group))
         }
diff --git a/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt b/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
index 6cde7a7..674a907 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
@@ -158,7 +158,7 @@
             val visitor = invocation.arguments[1] as ProtoLogCallVisitor
 
             visitor.processCall(code.findAll(MethodCallExpr::class.java)[0], "test %d %f",
-                    LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"))
+                    LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"), 123)
 
             invocation.arguments[0] as CompilationUnit
         }
@@ -195,11 +195,11 @@
 
             val calls = code.findAll(MethodCallExpr::class.java)
             visitor.processCall(calls[0], "test %d %f",
-                    LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"))
+                    LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"), 456)
             visitor.processCall(calls[1], "test %d %f",
-                    LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"))
+                    LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"), 789)
             visitor.processCall(calls[2], "test %d %f",
-                    LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"))
+                    LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"), 123)
 
             invocation.arguments[0] as CompilationUnit
         }
@@ -236,7 +236,7 @@
 
             visitor.processCall(code.findAll(MethodCallExpr::class.java)[0],
                     "test %d %f abc %s\n test", LogLevel.WARN, LogGroup("TEST_GROUP",
-                    true, true, "WM_TEST"))
+                    true, true, "WM_TEST"), 123)
 
             invocation.arguments[0] as CompilationUnit
         }
@@ -273,7 +273,7 @@
             val visitor = invocation.arguments[1] as ProtoLogCallVisitor
 
             visitor.processCall(code.findAll(MethodCallExpr::class.java)[0], "test",
-                    LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"))
+                    LogLevel.WARN, LogGroup("TEST_GROUP", true, true, "WM_TEST"), 456)
 
             invocation.arguments[0] as CompilationUnit
         }
@@ -307,7 +307,7 @@
             val visitor = invocation.arguments[1] as ProtoLogCallVisitor
 
             visitor.processCall(code.findAll(MethodCallExpr::class.java)[0], "test %d %f",
-                    LogLevel.WARN, LogGroup("TEST_GROUP", true, false, "WM_TEST"))
+                    LogLevel.WARN, LogGroup("TEST_GROUP", true, false, "WM_TEST"), 789)
 
             invocation.arguments[0] as CompilationUnit
         }
@@ -344,7 +344,7 @@
 
             visitor.processCall(code.findAll(MethodCallExpr::class.java)[0],
                     "test %d %f abc %s\n test", LogLevel.WARN, LogGroup("TEST_GROUP",
-                    true, false, "WM_TEST"))
+                    true, false, "WM_TEST"), 123)
 
             invocation.arguments[0] as CompilationUnit
         }
diff --git a/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigJsonBuilderTest.kt b/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigJsonBuilderTest.kt
index 1a20d4c..bcbc879 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigJsonBuilderTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigJsonBuilderTest.kt
@@ -50,9 +50,9 @@
     fun processClass() {
         val logCallRegistry = ProtoLogTool.LogCallRegistry()
         logCallRegistry.addLogCalls(listOf(
-                LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH),
-                LogCall(TEST2.messageString, LogLevel.DEBUG, GROUP2, PATH),
-                LogCall(TEST3.messageString, LogLevel.ERROR, GROUP3, PATH)))
+                LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH, 123),
+                LogCall(TEST2.messageString, LogLevel.DEBUG, GROUP2, PATH, 456),
+                LogCall(TEST3.messageString, LogLevel.ERROR, GROUP3, PATH, 789)))
 
         val parsedConfig = parseConfig(
             configBuilder.build(GROUPS, logCallRegistry.getStatements()).toString(Charsets.UTF_8))
@@ -69,9 +69,9 @@
     fun processClass_nonUnique() {
         val logCallRegistry = ProtoLogTool.LogCallRegistry()
         logCallRegistry.addLogCalls(listOf(
-                LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH),
-                LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH),
-                LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH)))
+                LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH, 123),
+                LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH, 456),
+                LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH, 789)))
 
         val parsedConfig = parseConfig(
             configBuilder.build(GROUPS, logCallRegistry.getStatements()).toString(Charsets.UTF_8))
diff --git a/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigProtoBuilderTest.kt b/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigProtoBuilderTest.kt
index 74a8de7..dfc6640 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigProtoBuilderTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/ViewerConfigProtoBuilderTest.kt
@@ -55,8 +55,8 @@
 
         val logCallRegistry = ProtoLogTool.LogCallRegistry()
         logCallRegistry.addLogCalls(listOf(
-            LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH),
-            LogCall(TEST2.messageString, LogLevel.INFO, GROUP2, PATH),
+            LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH, 123),
+            LogCall(TEST2.messageString, LogLevel.INFO, GROUP2, PATH, 456),
         ))
 
         val rawProto = configBuilder.build(GROUPS, logCallRegistry.getStatements())
@@ -65,4 +65,22 @@
         Truth.assertThat(viewerConfig.groupsCount).isEqualTo(GROUPS.size)
         Truth.assertThat(viewerConfig.messagesCount).isLessThan(GROUPS.size)
     }
+
+    @Test
+    fun includesLineNumberInLocation() {
+        val configBuilder = ViewerConfigProtoBuilder()
+
+        val logCallRegistry = ProtoLogTool.LogCallRegistry()
+        logCallRegistry.addLogCalls(listOf(
+            LogCall(TEST1.messageString, LogLevel.INFO, GROUP1, PATH, 123),
+            LogCall(TEST2.messageString, LogLevel.INFO, GROUP2, PATH, 456),
+        ))
+
+        val rawProto = configBuilder.build(GROUPS, logCallRegistry.getStatements())
+
+        val viewerConfig = ProtoLogViewerConfig.parseFrom(rawProto)
+
+        Truth.assertThat(viewerConfig.messagesList[0].location).isEqualTo("$PATH:123")
+        Truth.assertThat(viewerConfig.messagesList[1].location).isEqualTo("$PATH:456")
+    }
 }
\ No newline at end of file
diff --git a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
index 100d869..c51c6d6 100644
--- a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
+++ b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
@@ -17,8 +17,12 @@
 package com.android.systemfeatures
 
 import android.annotation.SdkConstant
+import com.squareup.javapoet.ClassName
+import com.squareup.javapoet.CodeBlock
 import com.squareup.javapoet.FieldSpec
 import com.squareup.javapoet.JavaFile
+import com.squareup.javapoet.MethodSpec
+import com.squareup.javapoet.ParameterizedTypeName
 import com.squareup.javapoet.TypeSpec
 import java.io.IOException
 import javax.annotation.processing.AbstractProcessor
@@ -27,6 +31,7 @@
 import javax.lang.model.SourceVersion
 import javax.lang.model.element.Modifier
 import javax.lang.model.element.TypeElement
+import javax.lang.model.element.VariableElement
 import javax.tools.Diagnostic
 
 /*
@@ -35,7 +40,16 @@
  * <p>The output is a single class file, `com.android.internal.pm.SystemFeaturesMetadata`, with
  * properties computed from feature constant definitions in the PackageManager class. This
  * class is only produced if the processed environment includes PackageManager; all other
- * invocations are ignored.
+ * invocations are ignored. The generated API is as follows:
+ *
+ * <pre>
+ * package android.content.pm;
+ * public final class SystemFeaturesMetadata {
+ *     public static final int SDK_FEATURE_COUNT;
+ *     // @return [0, SDK_FEATURE_COUNT) if an SDK-defined system feature, -1 otherwise.
+ *     public static int maybeGetSdkFeatureIndex(String featureName);
+ * }
+ * </pre>
  */
 class SystemFeaturesMetadataProcessor : AbstractProcessor() {
 
@@ -56,19 +70,31 @@
             return false
         }
 
-        // We're only interested in feature constants defined in PackageManager.
-        var featureCount = 0
-        roundEnv.getElementsAnnotatedWith(SdkConstant::class.java).forEach {
-            if (
-                it.enclosingElement == packageManagerType &&
-                    it.getAnnotation(SdkConstant::class.java).value ==
-                        SdkConstant.SdkConstantType.FEATURE
-            ) {
-                featureCount++
-            }
-        }
+        // Collect all FEATURE-annotated fields from PackageManager, and
+        //  1) Use the field values to de-duplicate, as there can be multiple FEATURE_* fields that
+        //     map to the same feature string name value.
+        //  2) Ensure they're sorted to ensure consistency and determinism between builds.
+        val featureVarNames =
+            roundEnv
+                .getElementsAnnotatedWith(SdkConstant::class.java)
+                .asSequence()
+                .filter {
+                    it.enclosingElement == packageManagerType &&
+                        it.getAnnotation(SdkConstant::class.java).value ==
+                            SdkConstant.SdkConstantType.FEATURE
+                }
+                .mapNotNull { element ->
+                    (element as? VariableElement)?.let { varElement ->
+                        varElement.getConstantValue()?.toString() to
+                            varElement.simpleName.toString()
+                    }
+                }
+                .toMap()
+                .values
+                .sorted()
+                .toList()
 
-        if (featureCount == 0) {
+        if (featureVarNames.isEmpty()) {
             // This is fine, and happens for any environment that doesn't include PackageManager.
             return false
         }
@@ -77,16 +103,8 @@
             TypeSpec.classBuilder("SystemFeaturesMetadata")
                 .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
                 .addJavadoc("@hide")
-                .addField(
-                    FieldSpec.builder(Int::class.java, "SDK_FEATURE_COUNT")
-                        .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
-                        .addJavadoc(
-                            "The number of `@SdkConstant` features defined in PackageManager."
-                        )
-                        .addJavadoc("@hide")
-                        .initializer("\$L", featureCount)
-                        .build()
-                )
+                .addFeatureCount(featureVarNames)
+                .addFeatureIndexLookup(featureVarNames)
                 .build()
 
         try {
@@ -104,7 +122,71 @@
         return true
     }
 
+    private fun TypeSpec.Builder.addFeatureCount(
+        featureVarNames: Collection<String>
+    ): TypeSpec.Builder {
+        return addField(
+            FieldSpec.builder(Int::class.java, "SDK_FEATURE_COUNT")
+                .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
+                .addJavadoc(
+                    "# of {@link android.annotation.SdkConstant}` features in PackageManager."
+                )
+                .addJavadoc("\n\n@hide")
+                .initializer("\$L", featureVarNames.size)
+                .build()
+        )
+    }
+
+    private fun TypeSpec.Builder.addFeatureIndexLookup(
+        featureVarNames: Collection<String>
+    ): TypeSpec.Builder {
+        // NOTE: This was initially implemented in terms of a single, long switch() statement.
+        // However, this resulted in:
+        //   1) relatively large compiled code size for the lookup method (~20KB)
+        //   2) worse runtime lookup performance than a simple ArraySet
+        // The ArraySet approach adds just ~1KB to the code/image and is 2x faster at runtime.
+
+        // Provide the initial capacity of the ArraySet for efficiency.
+        addField(
+            FieldSpec.builder(
+                    ParameterizedTypeName.get(ARRAYSET_CLASS, ClassName.get(String::class.java)),
+                    "sFeatures",
+                )
+                .addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
+                .initializer("new ArraySet<>(\$L)", featureVarNames.size)
+                .build()
+        )
+
+        // Use a temp array + Collections.addAll() to minimizes the generated code size.
+        addStaticBlock(
+            CodeBlock.builder()
+                .add("final \$T[] features = {\n", String::class.java)
+                .indent()
+                .apply { featureVarNames.forEach { add("\$T.\$N,\n", PACKAGEMANAGER_CLASS, it) } }
+                .unindent()
+                .addStatement("}")
+                .addStatement("\$T.addAll(sFeatures, features)", COLLECTIONS_CLASS)
+                .build()
+        )
+
+        // Use ArraySet.indexOf to provide the implicit feature index mapping.
+        return addMethod(
+            MethodSpec.methodBuilder("maybeGetSdkFeatureIndex")
+                .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+                .addJavadoc("@return an index in [0, SDK_FEATURE_COUNT) for features defined ")
+                .addJavadoc("in PackageManager, else -1.")
+                .addJavadoc("\n\n@hide")
+                .returns(Int::class.java)
+                .addParameter(String::class.java, "featureName")
+                .addStatement("return sFeatures.indexOf(featureName)")
+                .build()
+        )
+    }
+
     companion object {
         private val SDK_CONSTANT_ANNOTATION_NAME = SdkConstant::class.qualifiedName
+        private val PACKAGEMANAGER_CLASS = ClassName.get("android.content.pm", "PackageManager")
+        private val ARRAYSET_CLASS = ClassName.get("android.util", "ArraySet")
+        private val COLLECTIONS_CLASS = ClassName.get("java.util", "Collections")
     }
 }
diff --git a/tools/systemfeatures/tests/src/ArraySet.java b/tools/systemfeatures/tests/src/ArraySet.java
new file mode 100644
index 0000000..0eb8f29
--- /dev/null
+++ b/tools/systemfeatures/tests/src/ArraySet.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+import java.util.ArrayList;
+
+/** Stub for testing, we extend ArrayList to get indexOf() for free. */
+public final class ArraySet<K> extends ArrayList<K> {
+    public ArraySet(int capacity) {
+        super(capacity);
+    }
+
+    @Override
+    public boolean add(K k) {
+        if (!contains(k)) {
+            return super.add(k);
+        }
+        return false;
+    }
+}
diff --git a/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java b/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java
index 4ffb5b9..74ce6da 100644
--- a/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java
+++ b/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java
@@ -16,10 +16,16 @@
 
 package com.android.systemfeatures;
 
+import static com.android.internal.pm.SystemFeaturesMetadata.maybeGetSdkFeatureIndex;
+
 import static com.google.common.truth.Truth.assertThat;
 
+import android.content.pm.PackageManager;
+
 import com.android.internal.pm.SystemFeaturesMetadata;
 
+import com.google.common.collect.Range;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -33,4 +39,17 @@
         // It defines 5 annotated features, and any/all other constants should be ignored.
         assertThat(SystemFeaturesMetadata.SDK_FEATURE_COUNT).isEqualTo(5);
     }
+
+    @Test
+    public void testSdkFeatureIndex() {
+        // Only SDK-defined features return valid indices.
+        final Range validIndexRange = Range.closedOpen(0, SystemFeaturesMetadata.SDK_FEATURE_COUNT);
+        assertThat(maybeGetSdkFeatureIndex(PackageManager.FEATURE_PC)).isIn(validIndexRange);
+        assertThat(maybeGetSdkFeatureIndex(PackageManager.FEATURE_VULKAN)).isIn(validIndexRange);
+        assertThat(maybeGetSdkFeatureIndex(PackageManager.FEATURE_NOT_ANNOTATED)).isEqualTo(-1);
+        assertThat(maybeGetSdkFeatureIndex(PackageManager.NOT_FEATURE)).isEqualTo(-1);
+        assertThat(maybeGetSdkFeatureIndex("foo")).isEqualTo(-1);
+        assertThat(maybeGetSdkFeatureIndex("0")).isEqualTo(-1);
+        assertThat(maybeGetSdkFeatureIndex("")).isEqualTo(-1);
+    }
 }