Merge "Ensure lock for unregisterActivityConfigurationListener" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index c768121..df4a3e5 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -100,6 +100,7 @@
         "framework-jobscheduler-job.flags-aconfig-java",
         "framework_graphics_flags_java_lib",
         "hwui_flags_java_lib",
+        "interaction_jank_monitor_flags_lib",
         "libcore_exported_aconfig_flags_lib",
         "libgui_flags_java_lib",
         "power_flags_lib",
@@ -1428,6 +1429,18 @@
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
+java_aconfig_library {
+    name: "android.app.appfunctions.exported-flags-aconfig-java",
+    aconfig_declarations: "android.app.appfunctions.flags-aconfig",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+    mode: "exported",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.permission",
+    ],
+    min_sdk_version: "30",
+}
+
 // Adaptive Auth
 aconfig_declarations {
     name: "android.adaptiveauth.flags-aconfig",
@@ -1578,3 +1591,17 @@
     aconfig_declarations: "dropbox_flags",
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
+
+// Zero Jank
+aconfig_declarations {
+    name: "interaction_jank_monitor_flags",
+    package: "com.android.internal.jank",
+    container: "system",
+    srcs: ["core/java/com/android/internal/jank/flags.aconfig"],
+}
+
+java_aconfig_library {
+    name: "interaction_jank_monitor_flags_lib",
+    aconfig_declarations: "interaction_jank_monitor_flags",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
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 3d25ed5..97c6e25 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -5808,9 +5808,10 @@
 
     static void dumpHelp(PrintWriter pw) {
         pw.println("Job Scheduler (jobscheduler) dump options:");
-        pw.println("  [-h] [package] ...");
+        pw.println("  [-h] [package] [--proto] ...");
         pw.println("    -h: print this help");
         pw.println("  [package] is an optional package name to limit the output to.");
+        pw.println("    --proto: output dump in protocol buffer format.");
     }
 
     /** Sort jobs by caller UID, then by Job ID. */
diff --git a/core/api/current.txt b/core/api/current.txt
index ddfd364..5685221 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -43963,11 +43963,11 @@
     field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT = "satellite_connection_hysteresis_sec_int";
     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_INACTIVITY_TIMEOUT_SEC_INT = "satellite_esos_inactivity_timeout_sec_int";
     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.carrier_roaming_nb_iot_ntn") public static final String KEY_SATELLITE_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT = "satellite_p2p_sms_inactivity_timeout_sec_int";
+    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";
+    field @FlaggedApi("com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn") public static final String KEY_SATELLITE_ROAMING_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT = "satellite_roaming_p2p_sms_inactivity_timeout_sec_int";
     field @FlaggedApi("com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn") public static final String KEY_SATELLITE_ROAMING_P2P_SMS_SUPPORTED_BOOL = "satellite_roaming_p2p_sms_supported_bool";
-    field @FlaggedApi("com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn") public static final String KEY_SATELLITE_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT = "satellite_screen_off_inactivity_timeout_sec_int";
+    field @FlaggedApi("com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn") public static final String KEY_SATELLITE_ROAMING_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT = "satellite_roaming_screen_off_inactivity_timeout_sec_int";
     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";
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 68063c4..b83be6b 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -66,6 +66,7 @@
 import android.os.Debug;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.IpcDataCache;
 import android.os.LocaleList;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -238,6 +239,44 @@
             new RateLimitingCache<>(10, 2);
 
     /**
+     * Query handler for mGetCurrentUserIdCache - returns a cached value of the current foreground
+     * user id if the backstage_power/android.app.cache_get_current_user_id flag is enabled.
+     */
+    private static final IpcDataCache.QueryHandler<Void, Integer> mGetCurrentUserIdQuery =
+            new IpcDataCache.QueryHandler<>() {
+                @Override
+                public Integer apply(Void query) {
+                    try {
+                        return getService().getCurrentUserId();
+                    } catch (RemoteException e) {
+                        throw e.rethrowFromSystemServer();
+                    }
+                }
+
+                @Override
+                public boolean shouldBypassCache(Void query) {
+                    // If the flag to enable the new caching behavior is off, bypass the cache.
+                    return !Flags.cacheGetCurrentUserId();
+                }
+            };
+
+    /** A cache which maintains the current foreground user id. */
+    private static final IpcDataCache<Void, Integer> mGetCurrentUserIdCache =
+            new IpcDataCache<>(1, IpcDataCache.MODULE_SYSTEM,
+                    /* api= */ "getCurrentUserId", /* cacheName= */ "CurrentUserIdCache",
+                    mGetCurrentUserIdQuery);
+
+    /**
+     * The current foreground user has changed - invalidate the cache. Currently only called from
+     * UserController when a user switch occurs.
+     * @hide
+     */
+    public static void invalidateGetCurrentUserIdCache() {
+        IpcDataCache.invalidateCache(
+                IpcDataCache.MODULE_SYSTEM, /* api= */ "getCurrentUserId");
+    }
+
+    /**
      * Map of callbacks that have registered for {@link UidFrozenStateChanged} events.
      * Will be called when a Uid has become frozen or unfrozen.
      */
@@ -5244,11 +5283,7 @@
     })
     @android.ravenwood.annotation.RavenwoodReplace
     public static int getCurrentUser() {
-        try {
-            return getService().getCurrentUserId();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        return mGetCurrentUserIdCache.query(null);
     }
 
     /** @hide */
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 789c99d..1b29b7a 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -168,7 +168,11 @@
     /**
      * @hide
      */
-    public static final int MAX_VIBRATION_LENGTH = 1000;
+    public static final int MAX_VIBRATION_LENGTH = 500;
+    /**
+     * @hide
+     */
+    public static final int MAX_SERIALIZED_VIBRATION_LENGTH = 32_768;
 
     private static final String TAG_CHANNEL = "channel";
     private static final String ATT_NAME = "name";
@@ -368,6 +372,9 @@
         if (Flags.notificationChannelVibrationEffectApi()) {
             mVibrationEffect =
                     in.readInt() != 0 ? VibrationEffect.CREATOR.createFromParcel(in) : null;
+            if (Flags.notifChannelCropVibrationEffects() && mVibrationEffect != null) {
+                mVibrationEffect = getTrimmedVibrationEffect(mVibrationEffect);
+            }
         }
         mUserLockedFields = in.readInt();
         mUserVisibleTaskShown = in.readByte() != 0;
@@ -582,6 +589,23 @@
         return input;
     }
 
+    // Returns trimmed vibration effect or null if not trimmable.
+    private VibrationEffect getTrimmedVibrationEffect(VibrationEffect effect) {
+        if (effect == null) {
+            return null;
+        }
+        // trim if possible; check serialized length; reject if it is still too long
+        VibrationEffect result = effect;
+        VibrationEffect trimmed = effect.cropToLengthOrNull(MAX_VIBRATION_LENGTH);
+        if (trimmed != null) {
+            result = trimmed;
+        }
+        if (vibrationToString(result).length() > MAX_SERIALIZED_VIBRATION_LENGTH) {
+            return null;
+        }
+        return result;
+    }
+
     /**
      * @hide
      */
@@ -685,6 +709,11 @@
     public void setVibrationPattern(long[] vibrationPattern) {
         this.mVibrationEnabled = vibrationPattern != null && vibrationPattern.length > 0;
         this.mVibrationPattern = vibrationPattern;
+        if (Flags.notifChannelCropVibrationEffects()) {
+            if (vibrationPattern != null && vibrationPattern.length > MAX_VIBRATION_LENGTH) {
+                this.mVibrationPattern = Arrays.copyOf(vibrationPattern, MAX_VIBRATION_LENGTH);
+            }
+        }
         if (Flags.notificationChannelVibrationEffectApi()) {
             try {
                 this.mVibrationEffect =
@@ -731,9 +760,21 @@
     public void setVibrationEffect(@Nullable VibrationEffect effect) {
         this.mVibrationEnabled = effect != null;
         this.mVibrationEffect = effect;
-        this.mVibrationPattern =
-                effect == null
-                ? null : effect.computeCreateWaveformOffOnTimingsOrNull();
+        if (Flags.notifChannelCropVibrationEffects() && effect != null) {
+            // Try converting to a vibration pattern and trimming that array. If not convertible
+            // to a pattern directly, try trimming the vibration effect if possible and storing
+            // that version instead.
+            long[] pattern = effect.computeCreateWaveformOffOnTimingsOrNull();
+            if (pattern != null) {
+                setVibrationPattern(pattern);
+            } else {
+                this.mVibrationEffect = getTrimmedVibrationEffect(mVibrationEffect);
+            }
+        } else {
+            this.mVibrationPattern =
+                    mVibrationEffect == null
+                            ? null : mVibrationEffect.computeCreateWaveformOffOnTimingsOrNull();
+        }
     }
 
     /**
@@ -1172,7 +1213,9 @@
             if (vibrationEffect != null) {
                 // Restore the effect only if it is not null. This allows to avoid undoing a
                 // `setVibrationPattern` call above, if that was done with a non-null pattern
-                // (e.g. back up from a version that did not support `setVibrationEffect`).
+                // (e.g. back up from a version that did not support `setVibrationEffect`), or
+                // when notif_channel_crop_vibration_effects is true, if there is an equivalent
+                // vibration pattern available.
                 setVibrationEffect(vibrationEffect);
             }
         }
@@ -1365,7 +1408,11 @@
             out.attribute(null, ATT_VIBRATION, longArrayToString(getVibrationPattern()));
         }
         if (getVibrationEffect() != null) {
-            out.attribute(null, ATT_VIBRATION_EFFECT, vibrationToString(getVibrationEffect()));
+            if (!Flags.notifChannelCropVibrationEffects() || getVibrationPattern() == null) {
+                // When notif_channel_crop_vibration_effects is on, only serialize the vibration
+                // effect if we do not already have an equivalent vibration pattern.
+                out.attribute(null, ATT_VIBRATION_EFFECT, vibrationToString(getVibrationEffect()));
+            }
         }
         if (getUserLockedFields() != 0) {
             out.attributeInt(null, ATT_USER_LOCKED, getUserLockedFields());
diff --git a/core/java/android/app/activity_manager.aconfig b/core/java/android/app/activity_manager.aconfig
index 32e6e80..4c97dbb 100644
--- a/core/java/android/app/activity_manager.aconfig
+++ b/core/java/android/app/activity_manager.aconfig
@@ -104,3 +104,13 @@
      }
 }
 
+flag {
+     namespace: "backstage_power"
+     name: "cache_get_current_user_id"
+     description: "Add caching for getCurrentUserId"
+     is_fixed_read_only: true
+     bug: "361853873"
+     metadata {
+         purpose: PURPOSE_BUGFIX
+     }
+}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 1ddec17..0f54cb7 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -10476,10 +10476,6 @@
     @WorkerThread
     public void setApplicationRestrictions(@Nullable ComponentName admin, String packageName,
             Bundle settings) {
-        if (!Flags.dmrhSetAppRestrictions()) {
-            throwIfParentInstance("setApplicationRestrictions");
-        }
-
         if (mService != null) {
             try {
                 mService.setApplicationRestrictions(admin, mContext.getPackageName(), packageName,
@@ -11884,9 +11880,6 @@
     @WorkerThread
     public @NonNull Bundle getApplicationRestrictions(
             @Nullable ComponentName admin, String packageName) {
-        if (!Flags.dmrhSetAppRestrictions()) {
-            throwIfParentInstance("getApplicationRestrictions");
-        }
 
         if (mService != null) {
             try {
@@ -14231,21 +14224,11 @@
      */
     public @NonNull DevicePolicyManager getParentProfileInstance(@NonNull ComponentName admin) {
         throwIfParentInstance("getParentProfileInstance");
-        try {
-            if (Flags.dmrhSetAppRestrictions()) {
-                UserManager um = mContext.getSystemService(UserManager.class);
-                if (!um.isManagedProfile()) {
-                    throw new SecurityException("The current user does not have a parent profile.");
-                }
-            } else {
-                if (!mService.isManagedProfile(admin)) {
-                    throw new SecurityException("The current user does not have a parent profile.");
-                }
-            }
-            return new DevicePolicyManager(mContext, mService, true);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
+        UserManager um = mContext.getSystemService(UserManager.class);
+        if (!um.isManagedProfile()) {
+            throw new SecurityException("The current user does not have a parent profile.");
         }
+        return new DevicePolicyManager(mContext, mService, true);
     }
 
     /**
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index d9bd77f..faa5a91 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -97,6 +97,62 @@
   bug: "356894721"
 }
 
+flag {
+ name: "reset_password_with_token_coexistence"
+ is_exported: true
+ namespace: "enterprise"
+ description: "Enables coexistence support for resetPasswordWithToken and setResetPasswordToken."
+ bug: "359187209"
+}
+
+flag {
+ name: "set_keyguard_disabled_features_coexistence"
+ is_exported: true
+ namespace: "enterprise"
+ description: "Enables coexistence support for setKeyguardDisabledFeatures."
+ bug: "359186276"
+}
+
+flag {
+ name: "set_application_restrictions_coexistence"
+ is_exported: true
+ namespace: "enterprise"
+ description: "Enables coexistence support for setApplicationRestrictions."
+ bug: "359188153"
+}
+
+flag {
+ name: "set_auto_time_enabled_coexistence"
+ is_exported: true
+ namespace: "enterprise"
+ description: "Enables coexistence support for setAutoTimeEnabled."
+ bug: "359188869"
+}
+
+flag {
+ name: "set_backup_service_enabled_coexistence"
+ is_exported: true
+ namespace: "enterprise"
+ description: "Enables coexistence support for setBackupServiceEnabled."
+ bug: "359188483"
+}
+
+flag {
+ name: "set_auto_time_zone_enabled_coexistence"
+ is_exported: true
+ namespace: "enterprise"
+ description: "Enables coexistence support for setAutoTimeZoneEnabled."
+ bug: "364338300"
+}
+
+flag {
+ name: "set_permission_grant_state_coexistence"
+ is_exported: true
+ namespace: "enterprise"
+ description: "Enables coexistence support for setPermissionGrantState."
+ bug: "364338410"
+}
+
 # Fully rolled out and must not be used.
 flag {
   name: "security_log_v2_enabled"
@@ -210,16 +266,6 @@
 }
 
 flag {
-  name: "dmrh_set_app_restrictions"
-  namespace: "enterprise"
-  description: "Allow DMRH to set application restrictions (both on the profile and the parent)"
-  bug: "328758346"
-  metadata {
-    purpose: PURPOSE_BUGFIX
-  }
-}
-
-flag {
   name: "always_persist_do"
   namespace: "enterprise"
   description: "Always write device_owners2.xml so that migration flags aren't lost"
@@ -267,16 +313,6 @@
 }
 
 flag {
-    name: "headless_single_user_fixes"
-    namespace: "enterprise"
-    description: "Various fixes for headless single user mode"
-    bug: "289515470"
-    metadata {
-      purpose: PURPOSE_BUGFIX
-    }
-}
-
-flag {
     name: "backup_connected_apps_settings"
     namespace: "enterprise"
     description: "backup and restore connected work and personal apps user settings across devices"
diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig
index 606ca33..9891e89 100644
--- a/core/java/android/app/notification.aconfig
+++ b/core/java/android/app/notification.aconfig
@@ -128,6 +128,16 @@
 }
 
 flag {
+  name: "notif_channel_crop_vibration_effects"
+  namespace: "systemui"
+  description: "Limits the size of vibration effects that can be stored in a NotificationChannel"
+  bug: "345881518"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
   name: "evenly_divided_call_style_action_layout"
   namespace: "systemui"
   description: "Evenly divides horizontal space for action buttons in CallStyle notifications."
diff --git a/core/java/android/appwidget/flags.aconfig b/core/java/android/appwidget/flags.aconfig
index 4e0379e..7117f25 100644
--- a/core/java/android/appwidget/flags.aconfig
+++ b/core/java/android/appwidget/flags.aconfig
@@ -57,3 +57,10 @@
   description: "Enable support for persisting RemoteViews previews to Protobuf"
   bug: "306546610"
 }
+
+flag {
+  name: "remote_document_support"
+  namespace: "app_widgets"
+  description: "Remote document support features in Q2 2025 release"
+  bug: "339721781"
+}
\ No newline at end of file
diff --git a/core/java/android/companion/virtual/flags/flags.aconfig b/core/java/android/companion/virtual/flags/flags.aconfig
index 22a9ccf..297fe8a 100644
--- a/core/java/android/companion/virtual/flags/flags.aconfig
+++ b/core/java/android/companion/virtual/flags/flags.aconfig
@@ -111,3 +111,10 @@
     description: "Device awareness in power and display APIs"
     bug: "285020111"
 }
+
+flag {
+  name: "status_bar_and_insets"
+  namespace: "virtual_devices"
+  description: "Allow for status bar and insets on virtual devices"
+  bug: "350007866"
+}
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index 3a33ef9..28534ad 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -161,6 +161,16 @@
 }
 
 flag {
+    name: "fix_avatar_content_provider_null_authority"
+    namespace: "multiuser"
+    description: "Fix crash when content provider authority is null."
+    bug: "362880068"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
     name: "fix_avatar_picker_not_responding_for_new_user"
     namespace: "multiuser"
     description: "Avatar picker is not responding after selecting photo for new user."
diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
index fc72db3..6682b36 100644
--- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
@@ -61,7 +61,6 @@
             BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL,
             BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED,
             BIOMETRIC_ERROR_RE_ENROLL,
-            BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED,
             FINGERPRINT_ERROR_UNKNOWN,
             FINGERPRINT_ERROR_BAD_CALIBRATION,
             BIOMETRIC_ERROR_POWER_PRESSED})
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index 3a58993..218b023 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -256,6 +256,10 @@
     @Deprecated
     @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     public int[] getContextHubHandles() {
+        if (Flags.removeOldContextHubApis()) {
+            return null;
+        }
+
         try {
             return mService.getContextHubHandles();
         } catch (RemoteException e) {
@@ -277,6 +281,10 @@
     @Deprecated
     @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     public ContextHubInfo getContextHubInfo(int hubHandle) {
+        if (Flags.removeOldContextHubApis()) {
+            return null;
+        }
+
         try {
             return mService.getContextHubInfo(hubHandle);
         } catch (RemoteException e) {
@@ -308,6 +316,10 @@
     @Deprecated
     @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     public int loadNanoApp(int hubHandle, @NonNull NanoApp app) {
+        if (Flags.removeOldContextHubApis()) {
+            return -1;
+        }
+
         try {
             return mService.loadNanoApp(hubHandle, app);
         } catch (RemoteException e) {
@@ -335,6 +347,10 @@
     @Deprecated
     @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     public int unloadNanoApp(int nanoAppHandle) {
+        if (Flags.removeOldContextHubApis()) {
+            return -1;
+        }
+
         try {
             return mService.unloadNanoApp(nanoAppHandle);
         } catch (RemoteException e) {
@@ -375,6 +391,10 @@
     @Deprecated
     @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Nullable public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppHandle) {
+        if (Flags.removeOldContextHubApis()) {
+            return null;
+        }
+
         try {
             return mService.getNanoAppInstanceInfo(nanoAppHandle);
         } catch (RemoteException e) {
@@ -398,6 +418,10 @@
     @Deprecated
     @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @NonNull public int[] findNanoAppOnHub(int hubHandle, @NonNull NanoAppFilter filter) {
+        if (Flags.removeOldContextHubApis()) {
+            return null;
+        }
+
         try {
             return mService.findNanoAppOnHub(hubHandle, filter);
         } catch (RemoteException e) {
@@ -433,6 +457,10 @@
     @Deprecated
     @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     public int sendMessage(int hubHandle, int nanoAppHandle, @NonNull ContextHubMessage message) {
+        if (Flags.removeOldContextHubApis()) {
+            return -1;
+        }
+
         try {
             return mService.sendMessage(hubHandle, nanoAppHandle, message);
         } catch (RemoteException e) {
@@ -648,6 +676,10 @@
     @Deprecated
     @SuppressLint("RequiresPermission")
     public int registerCallback(@NonNull Callback callback) {
+        if (Flags.removeOldContextHubApis()) {
+            return -1;
+        }
+
         return registerCallback(callback, null);
     }
 
@@ -657,6 +689,10 @@
      */
     @Deprecated
     public int registerCallback(ICallback callback) {
+        if (Flags.removeOldContextHubApis()) {
+            return -1;
+        }
+
         if (mLocalCallback != null) {
             Log.w(TAG, "Max number of local callbacks reached!");
             return -1;
@@ -682,6 +718,10 @@
     @Deprecated
     @SuppressLint("RequiresPermission")
     public int registerCallback(Callback callback, Handler handler) {
+        if (Flags.removeOldContextHubApis()) {
+            return -1;
+        }
+
         synchronized(this) {
             if (mCallback != null) {
                 Log.w(TAG, "Max number of callbacks reached!");
@@ -1041,16 +1081,20 @@
     @SuppressLint("RequiresPermission")
     @Deprecated
     public int unregisterCallback(@NonNull Callback callback) {
-      synchronized(this) {
-          if (callback != mCallback) {
-              Log.w(TAG, "Cannot recognize callback!");
-              return -1;
-          }
+        if (Flags.removeOldContextHubApis()) {
+            return -1;
+        }
 
-          mCallback = null;
-          mCallbackHandler = null;
-      }
-      return 0;
+        synchronized (this) {
+            if (callback != mCallback) {
+                Log.w(TAG, "Cannot recognize callback!");
+                return -1;
+            }
+
+            mCallback = null;
+            mCallbackHandler = null;
+        }
+        return 0;
     }
 
     /**
@@ -1059,6 +1103,10 @@
      */
     @Deprecated
     public synchronized int unregisterCallback(ICallback callback) {
+        if (Flags.removeOldContextHubApis()) {
+            return -1;
+        }
+
         if (callback != mLocalCallback) {
             Log.w(TAG, "Cannot recognize local callback!");
             return -1;
diff --git a/core/java/android/os/ArtModuleServiceManager.java b/core/java/android/os/ArtModuleServiceManager.java
index e0b631d..995094b 100644
--- a/core/java/android/os/ArtModuleServiceManager.java
+++ b/core/java/android/os/ArtModuleServiceManager.java
@@ -37,10 +37,12 @@
     /** A class that exposes the method to obtain each system service. */
     public static final class ServiceRegisterer {
         @NonNull private final String mServiceName;
+        private final boolean mRetry;
 
         /** @hide */
-        public ServiceRegisterer(@NonNull String serviceName) {
+        public ServiceRegisterer(@NonNull String serviceName, boolean retry) {
             mServiceName = serviceName;
+            mRetry = retry;
         }
 
         /**
@@ -53,27 +55,47 @@
          */
         @Nullable
         public IBinder waitForService() {
-            return ServiceManager.waitForService(mServiceName);
+            if (mRetry) {
+                return ServiceManager.waitForService(mServiceName);
+            }
+            IBinder binder = ServiceManager.getService(mServiceName);
+            for (int remainingTimeMs = 5000; binder == null && remainingTimeMs > 0;
+                    remainingTimeMs -= 100) {
+                // There can be a race:
+                // 1. Client A invokes "ctl.start", which starts the service.
+                // 2. Client A gets a service handle from `ServiceManager.getService`.
+                // 3. Client B invokes "ctl.start", which does nothing because the service is
+                //    already running.
+                // 4. Client A drops the service handle. The service is notified that there is no
+                //    more client at that point, so it shuts down itself.
+                // 5. Client B cannot get a service handle from `ServiceManager.getService` because
+                //    the service is shut down.
+                // To address this problem, we invoke "ctl.start" repeatedly.
+                SystemProperties.set("ctl.start", mServiceName);
+                SystemClock.sleep(100);
+                binder = ServiceManager.getService(mServiceName);
+            }
+            return binder;
         }
     }
 
     /** Returns {@link ServiceRegisterer} for the "artd" service. */
     @NonNull
     public ServiceRegisterer getArtdServiceRegisterer() {
-        return new ServiceRegisterer("artd");
+        return new ServiceRegisterer("artd", true /* retry */);
     }
 
     /** Returns {@link ServiceRegisterer} for the "artd_pre_reboot" service. */
     @NonNull
     @FlaggedApi(Flags.FLAG_USE_ART_SERVICE_V2)
     public ServiceRegisterer getArtdPreRebootServiceRegisterer() {
-        return new ServiceRegisterer("artd_pre_reboot");
+        return new ServiceRegisterer("artd_pre_reboot", false /* retry */);
     }
 
     /** Returns {@link ServiceRegisterer} for the "dexopt_chroot_setup" service. */
     @NonNull
     @FlaggedApi(Flags.FLAG_USE_ART_SERVICE_V2)
     public ServiceRegisterer getDexoptChrootSetupServiceRegisterer() {
-        return new ServiceRegisterer("dexopt_chroot_setup");
+        return new ServiceRegisterer("dexopt_chroot_setup", true /* retry */);
     }
 }
diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java
index 1100731..c22f46c 100644
--- a/core/java/android/os/BinderProxy.java
+++ b/core/java/android/os/BinderProxy.java
@@ -646,6 +646,37 @@
     private native boolean unlinkToDeathNative(DeathRecipient recipient, int flags);
 
     /**
+     * This list is to hold strong reference to the frozen state callbacks. The callbacks are only
+     * weakly referenced by JNI so the strong references here are needed to keep the callbacks
+     * around until the proxy is GC'ed.
+     */
+    private List<IFrozenStateChangeCallback> mFrozenStateChangeCallbacks =
+            Collections.synchronizedList(new ArrayList<>());
+
+    /**
+     * See {@link IBinder#addFrozenStateChangeCallback(IFrozenStateChangeCallback)}
+     */
+    public void addFrozenStateChangeCallback(IFrozenStateChangeCallback callback)
+            throws RemoteException {
+        addFrozenStateChangeCallbackNative(callback);
+        mFrozenStateChangeCallbacks.add(callback);
+    }
+
+    /**
+     * See {@link IBinder#removeFrozenStateChangeCallback}
+     */
+    public boolean removeFrozenStateChangeCallback(IFrozenStateChangeCallback callback) {
+        mFrozenStateChangeCallbacks.remove(callback);
+        return removeFrozenStateChangeCallbackNative(callback);
+    }
+
+    private native void addFrozenStateChangeCallbackNative(IFrozenStateChangeCallback callback)
+            throws RemoteException;
+
+    private native boolean removeFrozenStateChangeCallbackNative(
+            IFrozenStateChangeCallback callback);
+
+    /**
      * Perform a dump on the remote object
      *
      * @param fd The raw file descriptor that the dump is being sent to.
@@ -730,6 +761,17 @@
         }
     }
 
+    private static void invokeFrozenStateChangeCallback(
+            IFrozenStateChangeCallback callback, IBinder binderProxy, int stateIndex) {
+        try {
+            callback.onFrozenStateChanged(binderProxy,
+                    IFrozenStateChangeCallback.State.values()[stateIndex]);
+        } catch (RuntimeException exc) {
+            Log.w("BinderNative", "Uncaught exception from frozen state change callback",
+                    exc);
+        }
+    }
+
     /**
      * C++ pointer to BinderProxyNativeData. That consists of strong pointers to the
      * native IBinder object, and a DeathRecipientList.
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index 50242ba..8185e8e 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -376,4 +376,53 @@
      * return value instead.
      */
     public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags);
+
+    /** @hide */
+    interface IFrozenStateChangeCallback {
+        enum State {FROZEN, UNFROZEN};
+
+        /**
+         * Interface for receiving a callback when the process hosting an IBinder
+         * has changed its frozen state.
+         * @param who The IBinder whose hosting process has changed state.
+         * @param state The latest state.
+         */
+        void onFrozenStateChanged(@NonNull IBinder who, State state);
+    }
+
+    /**
+     * {@link addFrozenStateChangeCallback} provides a callback mechanism to notify about process
+     * frozen/unfrozen events. Upon registration and any subsequent state changes, the callback is
+     * invoked with the latest process frozen state.
+     *
+     * <p>If the listener process (the one using this API) is itself frozen, state change events
+     * might be combined into a single one with the latest frozen state. This single event would
+     * then be delivered when the listener process becomes unfrozen. Similarly, if an event happens
+     * before the previous event is consumed, they might be combined. This means the callback might
+     * not be called for every single state change, so don't rely on this API to count how many
+     * times the state has changed.</p>
+     *
+     * <p>The callback is automatically removed when all references to the binder proxy are
+     * dropped.</p>
+     *
+     * <p>You will only receive state change notifications for remote binders, as local binders by
+     * definition can't be frozen without you being frozen too.</p>
+     *
+     * <p>@throws {@link UnsupportedOperationException} if the kernel binder driver does not support
+     * this feature.
+     * @hide
+     */
+    default void addFrozenStateChangeCallback(@NonNull IFrozenStateChangeCallback callback)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Unregister a {@link IFrozenStateChangeCallback}. The callback will no longer be invoked when
+     * the hosting process changes its frozen state.
+     * @hide
+     */
+    default boolean removeFrozenStateChangeCallback(@NonNull IFrozenStateChangeCallback callback) {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index f02d4a9..64a2dbc 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -540,6 +540,17 @@
     /** @hide */
     public abstract void validate();
 
+
+    /**
+     * If supported, truncate the length of this vibration effect to the provided length and return
+     * the result. Will always return null for repeating effects.
+     *
+     * @return The desired effect, or {@code null} if truncation is not applicable.
+     * @hide
+     */
+    @Nullable
+    public abstract VibrationEffect cropToLengthOrNull(int length);
+
     /**
      * Gets the estimated duration of the vibration in milliseconds.
      *
@@ -866,6 +877,30 @@
             }
         }
 
+        /** @hide */
+        @Override
+        @Nullable
+        public VibrationEffect cropToLengthOrNull(int length) {
+            // drop repeating effects
+            if (mRepeatIndex >= 0) {
+                return null;
+            }
+
+            int segmentCount = mSegments.size();
+            if (segmentCount <= length) {
+                return this;
+            }
+
+            ArrayList truncated = new ArrayList(mSegments.subList(0, length));
+            Composed updated = new Composed(truncated, mRepeatIndex);
+            try {
+                updated.validate();
+            } catch (IllegalArgumentException e) {
+                return null;
+            }
+            return updated;
+        }
+
         @Override
         public long getDuration() {
             if (mRepeatIndex >= 0) {
@@ -1150,6 +1185,13 @@
                     "Vendor effect bundle must be non-empty");
         }
 
+        /** @hide */
+        @Override
+        @Nullable
+        public VibrationEffect cropToLengthOrNull(int length) {
+            return null;
+        }
+
         @Override
         public long getDuration() {
             return -1; // UNKNOWN
diff --git a/core/java/android/util/LocalLog.java b/core/java/android/util/LocalLog.java
index feb80cc..ca5798a 100644
--- a/core/java/android/util/LocalLog.java
+++ b/core/java/android/util/LocalLog.java
@@ -112,6 +112,11 @@
         }
     }
 
+    // @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+    public synchronized void clear() {
+        mLog.clear();
+    }
+
     public static class ReadOnlyLocalLog {
         private final LocalLog mLog;
         ReadOnlyLocalLog(LocalLog log) {
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 9e4b27d..2dda835 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -445,16 +445,20 @@
         // Jank due to unknown reasons.
         public static final int UNKNOWN = 0x80;
 
-        public JankData(long frameVsyncId, @JankType int jankType, long frameIntervalNs) {
+        public JankData(long frameVsyncId, @JankType int jankType, long frameIntervalNs,
+                long scheduledAppFrameTimeNs, long actualAppFrameTimeNs) {
             this.frameVsyncId = frameVsyncId;
             this.jankType = jankType;
             this.frameIntervalNs = frameIntervalNs;
-
+            this.scheduledAppFrameTimeNs = scheduledAppFrameTimeNs;
+            this.actualAppFrameTimeNs = actualAppFrameTimeNs;
         }
 
         public final long frameVsyncId;
         public final @JankType int jankType;
         public final long frameIntervalNs;
+        public final long scheduledAppFrameTimeNs;
+        public final long actualAppFrameTimeNs;
     }
 
     /**
diff --git a/core/java/android/window/BackAnimationAdapter.java b/core/java/android/window/BackAnimationAdapter.java
index 5eb34e6..153e153 100644
--- a/core/java/android/window/BackAnimationAdapter.java
+++ b/core/java/android/window/BackAnimationAdapter.java
@@ -16,9 +16,12 @@
 
 package android.window;
 
+import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.ArrayList;
+
 /**
  * Object that describes how to run a remote back animation.
  *
@@ -26,6 +29,7 @@
  */
 public class BackAnimationAdapter implements Parcelable {
     private final IBackAnimationRunner mRunner;
+    private int[] mSupportedAnimators;
 
     public BackAnimationAdapter(IBackAnimationRunner runner) {
         mRunner = runner;
@@ -33,12 +37,23 @@
 
     public BackAnimationAdapter(Parcel in) {
         mRunner = IBackAnimationRunner.Stub.asInterface(in.readStrongBinder());
+        mSupportedAnimators = new int[in.readInt()];
+        in.readIntArray(mSupportedAnimators);
     }
 
     public IBackAnimationRunner getRunner() {
         return mRunner;
     }
 
+    /** Update the latest animators in the system. */
+    public void updateSupportedAnimators(@NonNull ArrayList<Integer> animators) {
+        final int size = animators.size();
+        mSupportedAnimators = new int[size];
+        for (int i = size - 1; i >= 0; --i) {
+            mSupportedAnimators[i] = animators.get(i);
+        }
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -47,6 +62,8 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeStrongInterface(mRunner);
+        dest.writeInt(mSupportedAnimators.length);
+        dest.writeIntArray(mSupportedAnimators);
     }
 
     public static final @android.annotation.NonNull Creator<BackAnimationAdapter> CREATOR =
@@ -59,4 +76,19 @@
             return new BackAnimationAdapter[size];
         }
     };
+
+    /**
+     * Check if the back type is animatable.
+     */
+    public boolean isAnimatable(@BackNavigationInfo.BackTargetType int backType) {
+        if (mSupportedAnimators == null) {
+            return false;
+        }
+        for (int i = mSupportedAnimators.length - 1; i >= 0; --i) {
+            if (backType == mSupportedAnimators[i]) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index ebf87f1..cab6d8e 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -245,3 +245,10 @@
       purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "enable_desktop_windowing_persistence"
+    namespace: "lse_desktop_experience"
+    description: "Persists the desktop windowing session across reboots."
+    bug: "350456942"
+}
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java
index 53ef49b..d474c6d 100644
--- a/core/java/com/android/internal/jank/FrameTracker.java
+++ b/core/java/com/android/internal/jank/FrameTracker.java
@@ -127,7 +127,7 @@
     private Runnable mWaitForFinishTimedOut;
 
     private static class JankInfo {
-        long frameVsyncId;
+        final long frameVsyncId;
         long totalDurationNanos;
         boolean isFirstFrame;
         boolean hwuiCallbackFired;
@@ -135,29 +135,42 @@
         @JankType int jankType;
         @RefreshRate int refreshRate;
 
-        static JankInfo createFromHwuiCallback(long frameVsyncId, long totalDurationNanos,
-                boolean isFirstFrame) {
-            return new JankInfo(frameVsyncId, true, false, JANK_NONE, UNKNOWN_REFRESH_RATE,
-                    totalDurationNanos, isFirstFrame);
+        static JankInfo createFromHwuiCallback(
+                long frameVsyncId, long totalDurationNanos, boolean isFirstFrame) {
+            return new JankInfo(frameVsyncId).update(totalDurationNanos, isFirstFrame);
         }
 
-        static JankInfo createFromSurfaceControlCallback(long frameVsyncId,
-                @JankType int jankType, @RefreshRate int refreshRate) {
-            return new JankInfo(
-                    frameVsyncId, false, true, jankType, refreshRate, 0, false /* isFirstFrame */);
+        static JankInfo createFromSurfaceControlCallback(SurfaceControl.JankData jankStat) {
+            return new JankInfo(jankStat.frameVsyncId).update(jankStat);
         }
 
-        private JankInfo(long frameVsyncId, boolean hwuiCallbackFired,
-                boolean surfaceControlCallbackFired, @JankType int jankType,
-                @RefreshRate int refreshRate,
-                long totalDurationNanos, boolean isFirstFrame) {
+        private JankInfo(long frameVsyncId) {
             this.frameVsyncId = frameVsyncId;
-            this.hwuiCallbackFired = hwuiCallbackFired;
-            this.surfaceControlCallbackFired = surfaceControlCallbackFired;
-            this.jankType = jankType;
-            this.refreshRate = refreshRate;
-            this.totalDurationNanos = totalDurationNanos;
+            this.hwuiCallbackFired = false;
+            this.surfaceControlCallbackFired = false;
+            this.jankType = JANK_NONE;
+            this.refreshRate = UNKNOWN_REFRESH_RATE;
+            this.totalDurationNanos = 0;
+            this.isFirstFrame = false;
+        }
+
+        private JankInfo update(SurfaceControl.JankData jankStat) {
+            this.surfaceControlCallbackFired = true;
+            this.jankType = jankStat.jankType;
+            this.refreshRate = DisplayRefreshRate.getRefreshRate(jankStat.frameIntervalNs);
+            if (Flags.useSfFrameDuration()) {
+                this.totalDurationNanos = jankStat.actualAppFrameTimeNs;
+            }
+            return this;
+        }
+
+        private JankInfo update(long totalDurationNanos, boolean isFirstFrame) {
+            this.hwuiCallbackFired = true;
+            if (!Flags.useSfFrameDuration()) {
+                this.totalDurationNanos = totalDurationNanos;
+            }
             this.isFirstFrame = isFirstFrame;
+            return this;
         }
 
         @Override
@@ -457,16 +470,12 @@
                 if (!isInRange(jankStat.frameVsyncId)) {
                     continue;
                 }
-                int refreshRate = DisplayRefreshRate.getRefreshRate(jankStat.frameIntervalNs);
                 JankInfo info = findJankInfo(jankStat.frameVsyncId);
                 if (info != null) {
-                    info.surfaceControlCallbackFired = true;
-                    info.jankType = jankStat.jankType;
-                    info.refreshRate = refreshRate;
+                    info.update(jankStat);
                 } else {
                     mJankInfos.put((int) jankStat.frameVsyncId,
-                            JankInfo.createFromSurfaceControlCallback(
-                                    jankStat.frameVsyncId, jankStat.jankType, refreshRate));
+                            JankInfo.createFromSurfaceControlCallback(jankStat));
                 }
             }
             processJankInfos();
@@ -513,9 +522,7 @@
             }
             JankInfo info = findJankInfo(frameVsyncId);
             if (info != null) {
-                info.hwuiCallbackFired = true;
-                info.totalDurationNanos = totalDurationNanos;
-                info.isFirstFrame = isFirstFrame;
+                info.update(totalDurationNanos, isFirstFrame);
             } else {
                 mJankInfos.put((int) frameVsyncId, JankInfo.createFromHwuiCallback(
                         frameVsyncId, totalDurationNanos, isFirstFrame));
diff --git a/core/java/com/android/internal/jank/flags.aconfig b/core/java/com/android/internal/jank/flags.aconfig
new file mode 100644
index 0000000..b6b8bc5
--- /dev/null
+++ b/core/java/com/android/internal/jank/flags.aconfig
@@ -0,0 +1,10 @@
+package: "com.android.internal.jank"
+container: "system"
+
+flag {
+  name: "use_sf_frame_duration"
+  namespace: "android_platform_window_surfaces"
+  description: "Whether to get the frame duration from SurfaceFlinger, or HWUI"
+  bug: "354763298"
+  is_fixed_read_only: true
+}
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 4828393..58818f3 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -63,6 +63,9 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.InsetDrawable;
 import android.graphics.drawable.LayerDrawable;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.Looper;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.Pair;
@@ -114,6 +117,7 @@
 import com.android.window.flags.Flags;
 
 import java.util.List;
+import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
 /** @hide */
@@ -1348,8 +1352,15 @@
                     mCrossWindowBlurEnabled = enabled;
                     updateBackgroundBlurRadius();
                 };
+                // The executor to receive callback {@link mCrossWindowBlurEnabledListener}. It
+                // should be the executor for this {@link DecorView}'s ui thread (not necessarily
+                // the main thread).
+                final Executor executor = Looper.myLooper() == Looper.getMainLooper()
+                        ? getContext().getMainExecutor()
+                        : new HandlerExecutor(new Handler(Looper.myLooper()));
                 getContext().getSystemService(WindowManager.class)
-                        .addCrossWindowBlurEnabledListener(mCrossWindowBlurEnabledListener);
+                        .addCrossWindowBlurEnabledListener(
+                                executor, mCrossWindowBlurEnabledListener);
                 getViewTreeObserver().addOnPreDrawListener(mBackgroundBlurOnPreDrawListener);
             } else {
                 updateBackgroundBlurRadius();
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 46b4695..921b77d 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -56,11 +56,11 @@
 //#undef ALOGV
 //#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
 
-#define DEBUG_DEATH 0
-#if DEBUG_DEATH
-#define LOGDEATH ALOGD
+#define DEBUG_DEATH_FREEZE 0
+#if DEBUG_DEATH_FREEZE
+#define LOG_DEATH_FREEZE ALOGD
 #else
-#define LOGDEATH ALOGV
+#define LOG_DEATH_FREEZE ALOGV
 #endif
 
 using namespace android;
@@ -116,6 +116,7 @@
     jclass mClass;
     jmethodID mGetInstance;
     jmethodID mSendDeathNotice;
+    jmethodID mInvokeFrozenStateChangeCallback;
 
     // Object state.
     jfieldID mNativeData;  // Field holds native pointer to BinderProxyNativeData.
@@ -547,23 +548,59 @@
 
 // ----------------------------------------------------------------------------
 
-// Per-IBinder death recipient bookkeeping.  This is how we reconcile local jobject
-// death recipient references passed in through JNI with the permanent corresponding
-// JavaDeathRecipient objects.
+// A JavaRecipient receives either death notifications or frozen state change
+// callbacks from natve code (IBinder) and dispatch the notifications to its
+// corresponding Java listener object.
+//
+// A RecipientList keeps tracks of all JavaRecipients for an IBinder. This way
+// we can find a JavaRecipient given a Java listener object.
+//
+// The implementation is shared between death recipients and frozen state change
+// callbacks via template. For death recipients the template is instantiated as
+// follows:
+//
+//                   IBinder::DeathRecipient
+//                            ^
+//                            |
+//                        (inherits)
+//                            |
+//            JavaRecipient<IBinder::DeathRecipient> <----> RecipientList<IBinder::DeathRecipient>
+//                            ^
+//                            |
+//                        (inherits)
+//                            |
+//                    JavaDeathRecipient
+//
+//
+// The instantiation for frozen state change callbacks are:
+//
+//             IBinder::FrozenStateChangeCallback
+//                           ^
+//                           |
+//                       (inherits)
+//                           |
+//     JavaRecipient<IBinder::FrozenStateChangeCallback>
+//                           ^                ^
+//                           |                |
+//                       (inherits)           +--> RecipientList<IBinder::FrozenStateChangeCallback>
+//                           |
+//              JavaFrozenStateChangeCallback
 
-class JavaDeathRecipient;
+template <typename T>
+class JavaRecipient;
 
-class DeathRecipientList : public RefBase {
-    List< sp<JavaDeathRecipient> > mList;
+template <typename T>
+class RecipientList : public RefBase {
+    List<sp<JavaRecipient<T> > > mList;
     Mutex mLock;
 
 public:
-    DeathRecipientList();
-    ~DeathRecipientList();
+    RecipientList();
+    ~RecipientList();
 
-    void add(const sp<JavaDeathRecipient>& recipient);
-    void remove(const sp<JavaDeathRecipient>& recipient);
-    sp<JavaDeathRecipient> find(jobject recipient);
+    void add(const sp<JavaRecipient<T> >& recipient);
+    void remove(const sp<JavaRecipient<T> >& recipient);
+    sp<JavaRecipient<T> > find(jobject recipient);
 
     Mutex& lock();  // Use with care; specifically for mutual exclusion during binder death
 };
@@ -584,11 +621,113 @@
 #endif // __BIONIC__
 #endif // BINDER_DEATH_RECIPIENT_WEAK_FROM_JNI
 
-class JavaDeathRecipient : public IBinder::DeathRecipient
-{
+template <typename T>
+constexpr const char* logPrefix();
+
+template <>
+constexpr const char* logPrefix<IBinder::DeathRecipient>() {
+    return "[DEATH]";
+}
+
+template <>
+constexpr const char* logPrefix<IBinder::FrozenStateChangeCallback>() {
+    return "[FREEZE]";
+}
+
+template <typename T>
+class JavaRecipient : public T {
 public:
-    JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)
+    JavaRecipient(JNIEnv* env, jobject object, const sp<RecipientList<T> >& list,
+                  bool useWeakReference)
           : mVM(jnienv_to_javavm(env)), mObject(NULL), mObjectWeak(NULL), mList(list) {
+        if (useWeakReference) {
+            mObjectWeak = env->NewWeakGlobalRef(object);
+        } else {
+            mObject = env->NewGlobalRef(object);
+        }
+        // These objects manage their own lifetimes so are responsible for final bookkeeping.
+        // The list holds a strong reference to this object.
+        LOG_DEATH_FREEZE("%s Adding JavaRecipient %p to RecipientList %p", logPrefix<T>(), this,
+                         list.get());
+        list->add(this);
+    }
+
+    void clearReference() {
+        sp<RecipientList<T> > list = mList.promote();
+        if (list != NULL) {
+            LOG_DEATH_FREEZE("%s Removing JavaRecipient %p from RecipientList %p", logPrefix<T>(),
+                             this, list.get());
+            list->remove(this);
+        } else {
+            LOG_DEATH_FREEZE("%s clearReference() on JavaRecipient %p but RecipientList wp purged",
+                             logPrefix<T>(), this);
+        }
+    }
+
+    bool matches(jobject obj) {
+        bool result;
+        JNIEnv* env = javavm_to_jnienv(mVM);
+
+        if (mObject != NULL) {
+            result = env->IsSameObject(obj, mObject);
+        } else {
+            ScopedLocalRef<jobject> me(env, env->NewLocalRef(mObjectWeak));
+            result = env->IsSameObject(obj, me.get());
+        }
+        return result;
+    }
+
+    void warnIfStillLive() {
+        if (mObject != NULL) {
+            // Okay, something is wrong -- we have a hard reference to a live death
+            // recipient on the VM side, but the list is being torn down.
+            JNIEnv* env = javavm_to_jnienv(mVM);
+            ScopedLocalRef<jclass> objClassRef(env, env->GetObjectClass(mObject));
+            ScopedLocalRef<jstring> nameRef(env,
+                                            (jstring)env->CallObjectMethod(objClassRef.get(),
+                                                                           gClassOffsets.mGetName));
+            ScopedUtfChars nameUtf(env, nameRef.get());
+            if (nameUtf.c_str() != NULL) {
+                ALOGW("BinderProxy is being destroyed but the application did not call "
+                      "unlinkToDeath to unlink all of its death recipients beforehand.  "
+                      "Releasing leaked death recipient: %s",
+                      nameUtf.c_str());
+            } else {
+                ALOGW("BinderProxy being destroyed; unable to get DR object name");
+                env->ExceptionClear();
+            }
+        }
+    }
+
+protected:
+    virtual ~JavaRecipient() {
+        // ALOGI("Removing death ref: recipient=%p\n", mObject);
+        JNIEnv* env = javavm_to_jnienv(mVM);
+        if (mObject != NULL) {
+            env->DeleteGlobalRef(mObject);
+        } else {
+            env->DeleteWeakGlobalRef(mObjectWeak);
+        }
+    }
+
+    JavaVM* const mVM;
+
+    // If useWeakReference is false (e.g. JavaDeathRecipient when target sdk version < 35), the
+    // Java-side Recipient is strongly referenced from mObject initially, and may later be demoted
+    // to a weak reference (mObjectWeak), e.g. upon linkToDeath() and then after binderDied() is
+    // called.
+    // If useWeakReference is true, the strong reference is never made here (i.e. mObject == NULL
+    // always). Instead, the strong reference to the Java-side Recipient is made in
+    // BinderProxy.{mDeathRecipients,mFrozenStateChangeCallbacks}. In the native world, only the
+    // weak reference is kept.
+    jobject mObject;
+    jweak mObjectWeak;
+    wp<RecipientList<T> > mList;
+};
+
+class JavaDeathRecipient : public JavaRecipient<IBinder::DeathRecipient> {
+public:
+    static bool useWeakReference() {
         // b/298374304: For apps targeting Android V or beyond, we no longer hold the global JNI ref
         // to the death recipient objects. This is to prevent the memory leak which can happen when
         // the death recipient object internally has a strong reference to the proxy object. Under
@@ -604,25 +743,26 @@
         // reference to. If however you want to get binderDied() regardless of the proxy object's
         // lifecycle, keep a strong reference to the death recipient object by yourself.
 #ifdef BINDER_DEATH_RECIPIENT_WEAK_FROM_JNI
-        if (target_sdk_is_at_least_vic()) {
-            mObjectWeak = env->NewWeakGlobalRef(object);
-        } else
+        return target_sdk_is_at_least_vic();
+#else
+        return false;
 #endif
-        {
-            mObject = env->NewGlobalRef(object);
-        }
-        // These objects manage their own lifetimes so are responsible for final bookkeeping.
-        // The list holds a strong reference to this object.
-        LOGDEATH("Adding JDR %p to DRL %p", this, list.get());
-        list->add(this);
+    }
 
+    JavaDeathRecipient(JNIEnv* env, jobject object,
+                       const sp<RecipientList<IBinder::DeathRecipient> >& list)
+          : JavaRecipient(env, object, list, useWeakReference()) {
         gNumDeathRefsCreated.fetch_add(1, std::memory_order_relaxed);
         gcIfManyNewRefs(env);
     }
 
+    ~JavaDeathRecipient() {
+        gNumDeathRefsDeleted.fetch_add(1, std::memory_order_relaxed);
+    }
+
     void binderDied(const wp<IBinder>& who)
     {
-        LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
+        LOG_DEATH_FREEZE("Receiving binderDied() on JavaDeathRecipient %p\n", this);
         if (mObject == NULL && mObjectWeak == NULL) {
             return;
         }
@@ -662,7 +802,7 @@
         // with our containing DeathRecipientList so that we can't delete the global ref on mObject
         // while the list is being iterated.
         if (mObject != NULL) {
-            sp<DeathRecipientList> list = mList.promote();
+            auto list = mList.promote();
             if (list != NULL) {
                 AutoMutex _l(list->lock());
 
@@ -673,126 +813,96 @@
         }
     }
 
-    void clearReference()
-    {
-        sp<DeathRecipientList> list = mList.promote();
-        if (list != NULL) {
-            LOGDEATH("Removing JDR %p from DRL %p", this, list.get());
-            list->remove(this);
-        } else {
-            LOGDEATH("clearReference() on JDR %p but DRL wp purged", this);
-        }
-    }
-
-    bool matches(jobject obj) {
-        bool result;
-        JNIEnv* env = javavm_to_jnienv(mVM);
-
-        if (mObject != NULL) {
-            result = env->IsSameObject(obj, mObject);
-        } else {
-            ScopedLocalRef<jobject> me(env, env->NewLocalRef(mObjectWeak));
-            result = env->IsSameObject(obj, me.get());
-        }
-        return result;
-    }
-
-    void warnIfStillLive() {
-        if (mObject != NULL) {
-            // Okay, something is wrong -- we have a hard reference to a live death
-            // recipient on the VM side, but the list is being torn down.
-            JNIEnv* env = javavm_to_jnienv(mVM);
-            ScopedLocalRef<jclass> objClassRef(env, env->GetObjectClass(mObject));
-            ScopedLocalRef<jstring> nameRef(env,
-                    (jstring) env->CallObjectMethod(objClassRef.get(), gClassOffsets.mGetName));
-            ScopedUtfChars nameUtf(env, nameRef.get());
-            if (nameUtf.c_str() != NULL) {
-                ALOGW("BinderProxy is being destroyed but the application did not call "
-                        "unlinkToDeath to unlink all of its death recipients beforehand.  "
-                        "Releasing leaked death recipient: %s", nameUtf.c_str());
-            } else {
-                ALOGW("BinderProxy being destroyed; unable to get DR object name");
-                env->ExceptionClear();
-            }
-        }
-    }
-
-protected:
-    virtual ~JavaDeathRecipient()
-    {
-        //ALOGI("Removing death ref: recipient=%p\n", mObject);
-        gNumDeathRefsDeleted.fetch_add(1, std::memory_order_relaxed);
-        JNIEnv* env = javavm_to_jnienv(mVM);
-        if (mObject != NULL) {
-            env->DeleteGlobalRef(mObject);
-        } else {
-            env->DeleteWeakGlobalRef(mObjectWeak);
-        }
-    }
-
 private:
-    JavaVM* const mVM;
-
-    // If target sdk version < 35, the Java-side DeathRecipient is strongly referenced from mObject
-    // upon linkToDeath() and then after binderDied() is called, the strong reference is demoted to
-    // a weak reference (mObjectWeak).
-    // If target sdk version >= 35, the strong reference is never made here (i.e. mObject == NULL
-    // always). Instead, the strong reference to the Java-side DeathRecipient is made in
-    // BinderProxy.mDeathRecipients. In the native world, only the weak reference is kept.
-    jobject mObject;
-    jweak mObjectWeak;
-    wp<DeathRecipientList> mList;
-
     // Whether binderDied was called or not.
     bool mFired = false;
 };
 
+class JavaFrozenStateChangeCallback : public JavaRecipient<IBinder::FrozenStateChangeCallback> {
+public:
+    JavaFrozenStateChangeCallback(
+            JNIEnv* env, jobject object,
+            const sp<RecipientList<IBinder::FrozenStateChangeCallback> >& list)
+          : JavaRecipient(env, object, list, /*useWeakReference=*/true) {}
+
+    void onStateChanged(const wp<IBinder>& who, State state) {
+        LOG_DEATH_FREEZE("Receiving onStateChanged() on JavaFrozenStateChangeCallback %p. state: "
+                         "%s\n",
+                         this, state == State::FROZEN ? "FROZEN" : "UNFROZEN");
+        if (mObjectWeak == NULL) {
+            return;
+        }
+        JNIEnv* env = javavm_to_jnienv(mVM);
+        ScopedLocalRef<jobject> jBinderProxy(env, javaObjectForIBinder(env, who.promote()));
+
+        // Hold a local reference to the recipient. This may fail if the recipient is weakly
+        // referenced, in which case we can't deliver the notification.
+        ScopedLocalRef<jobject> jCallback(env, env->NewLocalRef(mObjectWeak));
+        if (jCallback.get() == NULL) {
+            return;
+        }
+        env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
+                                  gBinderProxyOffsets.mInvokeFrozenStateChangeCallback,
+                                  jCallback.get(), jBinderProxy.get(), state);
+        if (env->ExceptionCheck()) {
+            jthrowable excep = env->ExceptionOccurred();
+            binder_report_exception(env, excep,
+                                    "*** Uncaught exception returned from frozen state change "
+                                    "notification!");
+        }
+    }
+};
+
 // ----------------------------------------------------------------------------
 
-DeathRecipientList::DeathRecipientList() {
-    LOGDEATH("New DRL @ %p", this);
+template <typename T>
+RecipientList<T>::RecipientList() {
+    LOG_DEATH_FREEZE("%s New RecipientList @ %p", logPrefix<T>(), this);
 }
 
-DeathRecipientList::~DeathRecipientList() {
-    LOGDEATH("Destroy DRL @ %p", this);
+template <typename T>
+RecipientList<T>::~RecipientList() {
+    LOG_DEATH_FREEZE("%s Destroy RecipientList @ %p", logPrefix<T>(), this);
     AutoMutex _l(mLock);
 
-    // Should never happen -- the JavaDeathRecipient objects that have added themselves
+    // Should never happen -- the JavaRecipientList objects that have added themselves
     // to the list are holding references on the list object.  Only when they are torn
     // down can the list header be destroyed.
     if (mList.size() > 0) {
-        List< sp<JavaDeathRecipient> >::iterator iter;
-        for (iter = mList.begin(); iter != mList.end(); iter++) {
+        for (auto iter = mList.begin(); iter != mList.end(); iter++) {
             (*iter)->warnIfStillLive();
         }
     }
 }
 
-void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
+template <typename T>
+void RecipientList<T>::add(const sp<JavaRecipient<T> >& recipient) {
     AutoMutex _l(mLock);
 
-    LOGDEATH("DRL @ %p : add JDR %p", this, recipient.get());
+    LOG_DEATH_FREEZE("%s RecipientList @ %p : add JavaRecipient %p", logPrefix<T>(), this,
+                     recipient.get());
     mList.push_back(recipient);
 }
 
-void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) {
+template <typename T>
+void RecipientList<T>::remove(const sp<JavaRecipient<T> >& recipient) {
     AutoMutex _l(mLock);
 
-    List< sp<JavaDeathRecipient> >::iterator iter;
-    for (iter = mList.begin(); iter != mList.end(); iter++) {
+    for (auto iter = mList.begin(); iter != mList.end(); iter++) {
         if (*iter == recipient) {
-            LOGDEATH("DRL @ %p : remove JDR %p", this, recipient.get());
+            LOG_DEATH_FREEZE("%s RecipientList @ %p : remove JavaRecipient %p", logPrefix<T>(),
+                             this, recipient.get());
             mList.erase(iter);
             return;
         }
     }
 }
 
-sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) {
+template <typename T>
+sp<JavaRecipient<T> > RecipientList<T>::find(jobject recipient) {
     AutoMutex _l(mLock);
 
-    List< sp<JavaDeathRecipient> >::iterator iter;
-    for (iter = mList.begin(); iter != mList.end(); iter++) {
+    for (auto iter = mList.begin(); iter != mList.end(); iter++) {
         if ((*iter)->matches(recipient)) {
             return *iter;
         }
@@ -800,10 +910,14 @@
     return NULL;
 }
 
-Mutex& DeathRecipientList::lock() {
+template <typename T>
+Mutex& RecipientList<T>::lock() {
     return mLock;
 }
 
+using DeathRecipientList = RecipientList<IBinder::DeathRecipient>;
+using FrozenStateChangeCallbackList = RecipientList<IBinder::FrozenStateChangeCallback>;
+
 // ----------------------------------------------------------------------------
 
 namespace android {
@@ -821,6 +935,11 @@
     // Death recipients for mObject. Reference counted only because DeathRecipients
     // hold a weak reference that can be temporarily promoted.
     sp<DeathRecipientList> mOrgue;  // Death recipients for mObject.
+
+    // Frozen state change callbacks for mObject. Reference counted only because
+    // JavaFrozenStateChangeCallback hold a weak reference that can be
+    // temporarily promoted.
+    sp<FrozenStateChangeCallbackList> mFrozenStateChangCallbackList;
 };
 
 BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) {
@@ -840,12 +959,13 @@
     if (val->checkSubclass(&gBinderOffsets)) {
         // It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
         jobject object = static_cast<JavaBBinder*>(val.get())->object();
-        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
+        LOG_DEATH_FREEZE("objectForBinder %p: it's our own %p!\n", val.get(), object);
         return object;
     }
 
     BinderProxyNativeData* nativeData = new BinderProxyNativeData();
     nativeData->mOrgue = new DeathRecipientList;
+    nativeData->mFrozenStateChangCallbackList = new FrozenStateChangeCallbackList;
     nativeData->mObject = val;
 
     jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
@@ -1448,7 +1568,7 @@
     BinderProxyNativeData *nd = getBPNativeData(env, obj);
     IBinder* target = nd->mObject.get();
 
-    LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
+    LOG_DEATH_FREEZE("linkToDeath: binder=%p recipient=%p\n", target, recipient);
 
     if (!target->localBinder()) {
         DeathRecipientList* list = nd->mOrgue.get();
@@ -1479,15 +1599,15 @@
         return JNI_FALSE;
     }
 
-    LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
+    LOG_DEATH_FREEZE("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
 
     if (!target->localBinder()) {
         status_t err = NAME_NOT_FOUND;
 
         // If we find the matching recipient, proceed to unlink using that
         DeathRecipientList* list = nd->mOrgue.get();
-        sp<JavaDeathRecipient> origJDR = list->find(recipient);
-        LOGDEATH("   unlink found list %p and JDR %p", list, origJDR.get());
+        sp<JavaRecipient<IBinder::DeathRecipient> > origJDR = list->find(recipient);
+        LOG_DEATH_FREEZE("   unlink found list %p and JDR %p", list, origJDR.get());
         if (origJDR != NULL) {
             wp<IBinder::DeathRecipient> dr;
             err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
@@ -1513,11 +1633,85 @@
     return res;
 }
 
+static void android_os_BinderProxy_addFrozenStateChangeCallback(
+        JNIEnv* env, jobject obj,
+        jobject callback) // throws RemoteException
+{
+    if (callback == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return;
+    }
+
+    BinderProxyNativeData* nd = getBPNativeData(env, obj);
+    IBinder* target = nd->mObject.get();
+
+    LOG_DEATH_FREEZE("addFrozenStateChangeCallback: binder=%p callback=%p\n", target, callback);
+
+    if (!target->localBinder()) {
+        FrozenStateChangeCallbackList* list = nd->mFrozenStateChangCallbackList.get();
+        auto jfscc = sp<JavaFrozenStateChangeCallback>::make(env, callback, list);
+        status_t err = target->addFrozenStateChangeCallback(jfscc);
+        if (err != NO_ERROR) {
+            // Failure adding the callback, so clear its reference now.
+            jfscc->clearReference();
+            signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
+        }
+    }
+}
+
+static jboolean android_os_BinderProxy_removeFrozenStateChangeCallback(JNIEnv* env, jobject obj,
+                                                                       jobject callback) {
+    jboolean res = JNI_FALSE;
+    if (callback == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return res;
+    }
+
+    BinderProxyNativeData* nd = getBPNativeData(env, obj);
+    IBinder* target = nd->mObject.get();
+    if (target == NULL) {
+        ALOGW("Binder has been finalized when calling removeFrozenStateChangeCallback() with "
+              "callback=%p)\n",
+              callback);
+        return JNI_FALSE;
+    }
+
+    LOG_DEATH_FREEZE("removeFrozenStateChangeCallback: binder=%p callback=%p\n", target, callback);
+
+    if (!target->localBinder()) {
+        status_t err = NAME_NOT_FOUND;
+
+        // If we find the matching callback, proceed to unlink using that
+        FrozenStateChangeCallbackList* list = nd->mFrozenStateChangCallbackList.get();
+        sp<JavaRecipient<IBinder::FrozenStateChangeCallback> > origJFSCC = list->find(callback);
+        LOG_DEATH_FREEZE("   removeFrozenStateChangeCallback found list %p and JFSCC %p", list,
+                         origJFSCC.get());
+        if (origJFSCC != NULL) {
+            err = target->removeFrozenStateChangeCallback(origJFSCC);
+            if (err == NO_ERROR) {
+                origJFSCC->clearReference();
+            }
+        }
+
+        if (err == NO_ERROR || err == DEAD_OBJECT) {
+            res = JNI_TRUE;
+        } else {
+            jniThrowException(env, "java/util/NoSuchElementException",
+                              base::StringPrintf("Frozen state change callback does not exist (%s)",
+                                                 statusToString(err).c_str())
+                                      .c_str());
+        }
+    }
+
+    return res;
+}
+
 static void BinderProxy_destroy(void* rawNativeData)
 {
     BinderProxyNativeData * nativeData = (BinderProxyNativeData *) rawNativeData;
-    LOGDEATH("Destroying BinderProxy: binder=%p drl=%p\n",
-            nativeData->mObject.get(), nativeData->mOrgue.get());
+    LOG_DEATH_FREEZE("Destroying BinderProxy: binder=%p drl=%p fsccl=%p\n",
+                     nativeData->mObject.get(), nativeData->mOrgue.get(),
+                     nativeData->mFrozenStateChangCallbackList.get());
     delete nativeData;
     IPCThreadState::self()->flushCommands();
 }
@@ -1552,6 +1746,10 @@
     {"transactNative",      "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
     {"linkToDeathNative",   "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
     {"unlinkToDeathNative", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
+    {"addFrozenStateChangeCallbackNative",
+        "(Landroid/os/IBinder$IFrozenStateChangeCallback;)V", (void*)android_os_BinderProxy_addFrozenStateChangeCallback},
+    {"removeFrozenStateChangeCallbackNative",
+        "(Landroid/os/IBinder$IFrozenStateChangeCallback;)Z", (void*)android_os_BinderProxy_removeFrozenStateChangeCallback},
     {"getNativeFinalizer",  "()J", (void*)android_os_BinderProxy_getNativeFinalizer},
     {"getExtension",        "()Landroid/os/IBinder;", (void*)android_os_BinderProxy_getExtension},
 };
@@ -1574,6 +1772,10 @@
     gBinderProxyOffsets.mSendDeathNotice =
             GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
                                    "(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V");
+    gBinderProxyOffsets.mInvokeFrozenStateChangeCallback =
+            GetStaticMethodIDOrDie(env, clazz, "invokeFrozenStateChangeCallback",
+                                   "(Landroid/os/IBinder$IFrozenStateChangeCallback;Landroid/os/"
+                                   "IBinder;I)V");
     gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");
 
     clazz = FindClassOrDie(env, "java/lang/Class");
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 0f53164..17c89f8 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -2089,9 +2089,11 @@
         jobjectArray jJankDataArray = env->NewObjectArray(jankData.size(),
                 gJankDataClassInfo.clazz, nullptr);
         for (size_t i = 0; i < jankData.size(); i++) {
-            jobject jJankData = env->NewObject(gJankDataClassInfo.clazz, gJankDataClassInfo.ctor,
-                                               jankData[i].frameVsyncId, jankData[i].jankType,
-                                               jankData[i].frameIntervalNs);
+            jobject jJankData =
+                    env->NewObject(gJankDataClassInfo.clazz, gJankDataClassInfo.ctor,
+                                   jankData[i].frameVsyncId, jankData[i].jankType,
+                                   jankData[i].frameIntervalNs, jankData[i].scheduledAppFrameTimeNs,
+                                   jankData[i].actualAppFrameTimeNs);
             env->SetObjectArrayElement(jJankDataArray, i, jJankData);
             env->DeleteLocalRef(jJankData);
         }
@@ -2727,7 +2729,7 @@
     jclass jankDataClazz =
                 FindClassOrDie(env, "android/view/SurfaceControl$JankData");
     gJankDataClassInfo.clazz = MakeGlobalRefOrDie(env, jankDataClazz);
-    gJankDataClassInfo.ctor = GetMethodIDOrDie(env, gJankDataClassInfo.clazz, "<init>", "(JIJ)V");
+    gJankDataClassInfo.ctor = GetMethodIDOrDie(env, gJankDataClassInfo.clazz, "<init>", "(JIJJJ)V");
     jclass onJankDataListenerClazz =
             FindClassOrDie(env, "android/view/SurfaceControl$OnJankDataListener");
     gJankDataListenerClassInfo.clazz = MakeGlobalRefOrDie(env, onJankDataListenerClazz);
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 9a75d3a..54a3b32 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1183,7 +1183,7 @@
     <string name="copyUrl" msgid="6229645005987260230">"‏کپی URL"</string>
     <string name="selectTextMode" msgid="3225108910999318778">"انتخاب متن"</string>
     <string name="undo" msgid="3175318090002654673">"لغو"</string>
-    <string name="redo" msgid="7231448494008532233">"بازانجام"</string>
+    <string name="redo" msgid="7231448494008532233">"ازنو انجام دادن"</string>
     <string name="autofill" msgid="511224882647795296">"تکمیل خودکار"</string>
     <string name="textSelectionCABTitle" msgid="5151441579532476940">"انتخاب متن"</string>
     <string name="addToDictionary" msgid="8041821113480950096">"افزودن به واژه‌نامه"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 6312704..6df63d6 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -291,7 +291,7 @@
     <string name="notification_channel_security" msgid="8516754650348238057">"સુરક્ષા"</string>
     <string name="notification_channel_car_mode" msgid="2123919247040988436">"કાર મોડ"</string>
     <string name="notification_channel_account" msgid="6436294521740148173">"એકાઉન્ટ સ્થિતિ"</string>
-    <string name="notification_channel_developer" msgid="1691059964407549150">"વિકાસકર્તા માટેના સંદેશા"</string>
+    <string name="notification_channel_developer" msgid="1691059964407549150">"ડેવલપર માટેના મેસેજ"</string>
     <string name="notification_channel_developer_important" msgid="7197281908918789589">"ડેવલપર માટેના મહત્ત્વપૂર્ણ મેસેજ"</string>
     <string name="notification_channel_updates" msgid="7907863984825495278">"અપડેટ્સ"</string>
     <string name="notification_channel_network_status" msgid="2127687368725272809">"નેટવર્ક સ્થિતિ"</string>
@@ -400,7 +400,7 @@
     <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"આ ઍપ, તમારા Android TV ડિવાઇસ પર સંગ્રહિત તમામ SMS (ટેક્સ્ટ) મેસેજ વાંચી શકે છે."</string>
     <string name="permdesc_readSms" product="default" msgid="774753371111699782">"આ ઍપ, તમારા ફોન પર સંગ્રહિત તમામ SMS (ટેક્સ્ટ) મેસેજ વાંચી શકે છે."</string>
     <string name="permlab_receiveWapPush" msgid="4223747702856929056">"ટેક્સ્ટ મેસેજ  (WAP) મેળવો"</string>
-    <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"એપ્લિકેશનને WAP સંદેશા પ્રાપ્ત કરવાની અને તેના પર પ્રક્રિયા કરવાની મંજૂરી આપે છે. આ પરવાનગીમાં તમને દર્શાવ્યા વિના તમને મોકલેલ સંદેશાઓનું નિરીક્ષણ કરવાની અને કાઢી નાખવાની ક્ષમતાનો સમાવેશ થાય છે."</string>
+    <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"ઍપને WAP મેસેજ મેળવવાની અને તેના પર પ્રક્રિયા કરવાની મંજૂરી આપે છે. આ પરવાનગીમાં તમને દર્શાવ્યા વિના તમને મોકલેલા મેસેજનું નિરીક્ષણ કરવાની અને ડિલીટ કરવાની ક્ષમતાનો સમાવેશ થાય છે."</string>
     <string name="permlab_getTasks" msgid="7460048811831750262">"ચાલુ ઍપ્લિકેશનો પુનઃપ્રાપ્ત કરો"</string>
     <string name="permdesc_getTasks" msgid="7388138607018233726">"એપ્લિકેશનને વર્તમાનમાં અને તાજેતરમાં ચાલી રહેલ Tasks વિશેની વિગતવાર માહિતી પુનઃપ્રાપ્ત કરવાની મંજૂરી આપે છે. આ એપ્લિકેશનને ઉપકરણ પર કઈ એપ્લિકેશન્સનો ઉપયોગ થાય છે તેના વિશેની માહિતી શોધવાની મંજૂરી આપી શકે છે."</string>
     <string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"પ્રોફાઇલ અને ડિવાઇસ માલિકોને મેનેજ કરો"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 5106f7c..5593f41 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1721,7 +1721,7 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Verwijderen"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Volume verhogen tot boven het aanbevolen niveau?\n\nAls je langere tijd op hoog volume naar muziek luistert, raakt je gehoor mogelijk beschadigd."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Wil je blijven luisteren op hoog volume?\n\nHet hoofdtelefoonvolume is langer dan de aanbevolen tijd hoog geweest. Dit kan je gehoor beschadigen."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Wil je blijven luisteren op hoog volume?\n\nHet koptelefoonvolume is langer dan de aanbevolen tijd hoog geweest. Dit kan je gehoor beschadigen."</string>
     <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Hard geluid gedetecteerd\n\nHet hoofdtelefoonvolume is hoger dan aanbevolen. Dit kan je gehoor beschadigen."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Snelkoppeling toegankelijkheid gebruiken?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Als de snelkoppeling aanstaat, houd je beide volumeknoppen 3 seconden ingedrukt om een toegankelijkheidsfunctie te starten."</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 885be75..805dce5 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1721,7 +1721,7 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Alisin"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Lakasan ang volume nang lagpas sa inirerekomendang antas?\n\nMaaaring mapinsala ng pakikinig sa malakas na volume sa loob ng mahahabang panahon ang iyong pandinig."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Magpatuloy sa pakikinig nang may malakas na volume?\n\nNaging malakas ang volume nang mas matagal na sa inirerekomenda, at posible nitong mapinsala ang pandinig mo"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Magpatuloy sa pakikinig nang may malakas na volume?\n\nMalakas ang volume nang mas matagal na sa inirerekomenda, at posible nitong mapinsala ang pandinig mo"</string>
     <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Naka-detect ng malakas na tunog\n\nMas malakas ang volume kaysa sa inirerekomenda, at posible nitong mapinsala ang pandinig mo"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gagamitin ang Shortcut sa Accessibility?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kapag naka-on ang shortcut, magsisimula ang isang feature ng pagiging naa-access kapag pinindot ang parehong button ng volume."</string>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f404666..606c7fd 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4804,9 +4804,9 @@
     </string>
 
     <!-- Title for accessibility edit shortcut selection menu dialog, and dialog is triggered
-    from volume key shortcut. [CHAR LIMIT=100] -->
+    from volume keys shortcut. [CHAR LIMIT=100] -->
     <string name="accessibility_edit_shortcut_menu_volume_title">Choose features to use with the
-        volume key shortcut
+        volume keys shortcut
     </string>
 
     <!-- Text for showing the warning to user when uncheck the legacy app item in the accessibility
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 452ae04..d35bfb7 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">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/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>
@@ -351,7 +351,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -468,7 +468,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -587,7 +587,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -705,7 +705,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -831,7 +831,7 @@
         <item name="alertDialogTheme">@style/Theme.DeviceDefault.Dialog.Alert</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -948,7 +948,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -1064,7 +1064,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -1181,7 +1181,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -1314,7 +1314,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -1432,7 +1432,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -1548,7 +1548,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -1666,7 +1666,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -1783,7 +1783,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -1900,7 +1900,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -2017,7 +2017,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -2134,7 +2134,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -2251,7 +2251,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -2373,7 +2373,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -2488,7 +2488,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -2642,7 +2642,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">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/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>
@@ -2858,7 +2858,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -2974,7 +2974,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -3091,7 +3091,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -3210,7 +3210,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -3328,7 +3328,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -3452,7 +3452,7 @@
         <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -3572,7 +3572,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -3691,7 +3691,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -3811,7 +3811,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -4133,7 +4133,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -4254,7 +4254,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -4373,7 +4373,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -4491,7 +4491,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -4608,7 +4608,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -4725,7 +4725,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -4840,7 +4840,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -5066,7 +5066,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -5162,7 +5162,7 @@
         <item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -5280,7 +5280,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -5471,7 +5471,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -5522,7 +5522,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
@@ -5641,7 +5641,7 @@
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
 
         <!-- Progress bar attributes -->
-        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
         <!-- Toolbar attributes -->
diff --git a/core/tests/GameManagerTests/Android.bp b/core/tests/GameManagerTests/Android.bp
index 0e3bc65..a252f8b 100644
--- a/core/tests/GameManagerTests/Android.bp
+++ b/core/tests/GameManagerTests/Android.bp
@@ -37,3 +37,10 @@
     certificate: "platform",
     test_suites: ["device-tests"],
 }
+
+test_module_config {
+    name: "FrameworksCoreGameManagerTests_android_app",
+    base: "FrameworksCoreGameManagerTests",
+    test_suites: ["device-tests"],
+    include_filters: ["android.app"],
+}
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index b0e48f1..99cbf05 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -21,6 +21,7 @@
     srcs: [
         "DisabledTestApp/src/**/*.java",
         "EnabledTestApp/src/**/*.java",
+        "BinderFrozenStateChangeCallbackTestApp/src/**/*.java",
         "BinderProxyCountingTestApp/src/**/*.java",
         "BinderProxyCountingTestService/src/**/*.java",
         "BinderDeathRecipientHelperApp/src/**/*.java",
@@ -138,6 +139,7 @@
         ":BinderDeathRecipientHelperApp1",
         ":BinderDeathRecipientHelperApp2",
         ":com.android.cts.helpers.aosp",
+        ":BinderFrozenStateChangeCallbackTestApp",
         ":BinderProxyCountingTestApp",
         ":BinderProxyCountingTestService",
         ":AppThatUsesAppOps",
diff --git a/core/tests/coretests/AndroidTest.xml b/core/tests/coretests/AndroidTest.xml
index 99b73a4..b1f1e2c 100644
--- a/core/tests/coretests/AndroidTest.xml
+++ b/core/tests/coretests/AndroidTest.xml
@@ -22,6 +22,7 @@
         <option name="test-file-name" value="FrameworksCoreTests.apk" />
         <option name="test-file-name" value="BinderDeathRecipientHelperApp1.apk" />
         <option name="test-file-name" value="BinderDeathRecipientHelperApp2.apk" />
+        <option name="test-file-name" value="BinderFrozenStateChangeCallbackTestApp.apk" />
         <option name="test-file-name" value="BinderProxyCountingTestApp.apk" />
         <option name="test-file-name" value="BinderProxyCountingTestService.apk" />
         <option name="test-file-name" value="AppThatUsesAppOps.apk" />
diff --git a/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/Android.bp b/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/Android.bp
new file mode 100644
index 0000000..de97dda
--- /dev/null
+++ b/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/Android.bp
@@ -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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test_helper_app {
+    name: "BinderFrozenStateChangeCallbackTestApp",
+
+    static_libs: ["coretests-aidl"],
+    srcs: ["**/*.java"],
+
+    platform_apis: true,
+    certificate: "platform",
+
+    test_suites: ["device-tests"],
+}
diff --git a/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/AndroidManifest.xml b/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/AndroidManifest.xml
new file mode 100644
index 0000000..29c8f55
--- /dev/null
+++ b/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.frameworks.coretests.bfscctestapp">
+
+    <application>
+        <service android:name=".BfsccTestAppCmdService"
+                 android:exported="true"/>
+    </application>
+</manifest>
diff --git a/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/src/com/android/frameworks/coretests/bfscctestapp/BfsccTestAppCmdService.java b/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/src/com/android/frameworks/coretests/bfscctestapp/BfsccTestAppCmdService.java
new file mode 100644
index 0000000..77e8a40
--- /dev/null
+++ b/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/src/com/android/frameworks/coretests/bfscctestapp/BfsccTestAppCmdService.java
@@ -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.frameworks.coretests.bfscctestapp;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import com.android.frameworks.coretests.aidl.IBfsccTestAppCmdService;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+public class BfsccTestAppCmdService extends Service {
+    private IBfsccTestAppCmdService.Stub mBinder = new IBfsccTestAppCmdService.Stub() {
+        private final LinkedBlockingQueue<IBinder.IFrozenStateChangeCallback.State> mNotifications =
+                new LinkedBlockingQueue<>();
+
+        @Override
+        public void listenTo(IBinder binder) throws RemoteException {
+            binder.addFrozenStateChangeCallback(
+                    (IBinder who, IBinder.IFrozenStateChangeCallback.State state)
+                            -> mNotifications.offer(state));
+        }
+
+        @Override
+        public boolean[] waitAndConsumeNotifications() {
+            List<Boolean> results = new ArrayList<>();
+            try {
+                IBinder.IFrozenStateChangeCallback.State state =
+                        mNotifications.poll(5, TimeUnit.SECONDS);
+                if (state != null) {
+                    results.add(state == IBinder.IFrozenStateChangeCallback.State.FROZEN);
+                }
+            } catch (InterruptedException e) {
+                return null;
+            }
+            while (mNotifications.size() > 0) {
+                results.add(mNotifications.poll()
+                        == IBinder.IFrozenStateChangeCallback.State.FROZEN);
+            }
+            boolean[] convertedResults = new boolean[results.size()];
+            for (int i = 0; i < results.size(); i++) {
+                convertedResults[i] = results.get(i).booleanValue();
+            }
+            return convertedResults;
+        }
+    };
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+}
diff --git a/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BinderProxyCountingService.java b/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BinderProxyCountingService.java
index 41b4c69..09d79a6 100644
--- a/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BinderProxyCountingService.java
+++ b/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BinderProxyCountingService.java
@@ -50,4 +50,4 @@
     public IBinder onBind(Intent intent) {
         return mBinder;
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneActionsViewModelKosmos.kt b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBfsccTestAppCmdService.aidl
similarity index 63%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneActionsViewModelKosmos.kt
copy to core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBfsccTestAppCmdService.aidl
index 128a7fc..d8d7dc4 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneActionsViewModelKosmos.kt
+++ b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBfsccTestAppCmdService.aidl
@@ -14,13 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.ui.viewmodel
+package com.android.frameworks.coretests.aidl;
 
-import com.android.systemui.kosmos.Kosmos
-
-val Kosmos.quickSettingsShadeSceneActionsViewModel: QuickSettingsShadeSceneActionsViewModel by
-    Kosmos.Fixture {
-        QuickSettingsShadeSceneActionsViewModel(
-            quickSettingsContainerViewModel = quickSettingsContainerViewModel,
-        )
-    }
+interface IBfsccTestAppCmdService {
+   void listenTo(IBinder binder);
+   boolean[] waitAndConsumeNotifications();
+}
diff --git a/core/tests/coretests/src/android/app/NotificationChannelTest.java b/core/tests/coretests/src/android/app/NotificationChannelTest.java
index c08e42b..e47ef2d 100644
--- a/core/tests/coretests/src/android/app/NotificationChannelTest.java
+++ b/core/tests/coretests/src/android/app/NotificationChannelTest.java
@@ -233,6 +233,33 @@
     }
 
     @Test
+    @EnableFlags({Flags.FLAG_NOTIFICATION_CHANNEL_VIBRATION_EFFECT_API,
+            Flags.FLAG_NOTIF_CHANNEL_CROP_VIBRATION_EFFECTS})
+    public void testLongVibrationFields_canWriteToXml() throws Exception {
+        NotificationChannel channel = new NotificationChannel("id", "name", 3);
+        // populate pattern with contents
+        long[] pattern = new long[65550 / 2];
+        for (int i = 0; i < pattern.length; i++) {
+            pattern[i] = 100;
+        }
+        channel.setVibrationPattern(pattern);  // with flag on, also sets effect
+
+        // Send it through parceling & unparceling to simulate being passed through a binder call
+        NotificationChannel fromParcel = writeToAndReadFromParcel(channel);
+        assertThat(fromParcel.getVibrationPattern().length).isEqualTo(
+                NotificationChannel.MAX_VIBRATION_LENGTH);
+
+        // Confirm that this also survives writing to & restoring from XML
+        NotificationChannel result = backUpAndRestore(fromParcel);
+        assertThat(result.getVibrationPattern().length).isEqualTo(
+                NotificationChannel.MAX_VIBRATION_LENGTH);
+        assertThat(result.getVibrationEffect()).isNotNull();
+        assertThat(result.getVibrationEffect()
+                .computeCreateWaveformOffOnTimingsOrNull())
+                .isEqualTo(result.getVibrationPattern());
+    }
+
+    @Test
     public void testRestoreSoundUri_customLookup() throws Exception {
         Uri uriToBeRestoredUncanonicalized = Uri.parse("content://media/1");
         Uri uriToBeRestoredCanonicalized = Uri.parse("content://media/1?title=Song&canonical=1");
diff --git a/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java b/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java
new file mode 100644
index 0000000..ee2e7e0
--- /dev/null
+++ b/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.ravenwood.RavenwoodRule;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.UiDevice;
+
+import com.android.frameworks.coretests.aidl.IBfsccTestAppCmdService;
+import com.android.frameworks.coretests.bdr_helper_app.TestCommsReceiver;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Queue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Tests functionality of {@link android.os.IBinder.IFrozenStateChangeCallback}.
+ */
+@RunWith(AndroidJUnit4.class)
+@IgnoreUnderRavenwood(blockedBy = ActivityManager.class)
+public class BinderFrozenStateChangeNotificationTest {
+    private static final String TAG = BinderFrozenStateChangeNotificationTest.class.getSimpleName();
+
+    private static final String TEST_PACKAGE_NAME_1 =
+            "com.android.frameworks.coretests.bfscctestapp";
+    private static final String TEST_PACKAGE_NAME_2 =
+            "com.android.frameworks.coretests.bdr_helper_app1";
+    private static final String TEST_APP_CMD_SERVICE =
+            TEST_PACKAGE_NAME_1 + ".BfsccTestAppCmdService";
+
+    private static final int CALLBACK_WAIT_TIMEOUT_SECS = 5;
+
+    private IBfsccTestAppCmdService mBfsccTestAppCmdService;
+    private ServiceConnection mTestAppConnection;
+    private Context mContext;
+    private Handler mHandler;
+
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule();
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mHandler = new Handler(Looper.getMainLooper());
+        ((ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE)).killUid(
+                mContext.getPackageManager().getPackageUid(TEST_PACKAGE_NAME_1, 0),
+                "Wiping Test Package");
+        mTestAppConnection = bindService();
+    }
+
+    private IBinder getNewRemoteBinder(String testPackage) throws InterruptedException {
+        final CountDownLatch resultLatch = new CountDownLatch(1);
+        final AtomicInteger resultCode = new AtomicInteger(Activity.RESULT_CANCELED);
+        final AtomicReference<Bundle> resultExtras = new AtomicReference<>();
+
+        final Intent intent = new Intent(TestCommsReceiver.ACTION_GET_BINDER)
+                .setClassName(testPackage, TestCommsReceiver.class.getName());
+        mContext.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                resultCode.set(getResultCode());
+                resultExtras.set(getResultExtras(true));
+                resultLatch.countDown();
+            }
+        }, mHandler, Activity.RESULT_CANCELED, null, null);
+
+        assertTrue("Request for binder timed out", resultLatch.await(5, TimeUnit.SECONDS));
+        assertEquals(Activity.RESULT_OK, resultCode.get());
+        return resultExtras.get().getBinder(TestCommsReceiver.EXTRA_KEY_BINDER);
+    }
+
+    private ServiceConnection bindService()
+            throws Exception {
+        final CountDownLatch bindLatch = new CountDownLatch(1);
+        ServiceConnection connection = new ServiceConnection() {
+            @Override
+            public void onServiceConnected(ComponentName name, IBinder service) {
+                Log.i(TAG, "Service connected");
+                mBfsccTestAppCmdService = IBfsccTestAppCmdService.Stub.asInterface(service);
+                bindLatch.countDown();
+            }
+
+            @Override
+            public void onServiceDisconnected(ComponentName name) {
+                Log.i(TAG, "Service disconnected");
+            }
+        };
+        mContext.bindService(
+                new Intent().setComponent(
+                        new ComponentName(TEST_PACKAGE_NAME_1, TEST_APP_CMD_SERVICE)),
+                connection,
+                Context.BIND_AUTO_CREATE
+                        | Context.BIND_NOT_FOREGROUND);
+        if (!bindLatch.await(5, TimeUnit.SECONDS)) {
+            fail("Timed out waiting for the service to bind");
+        }
+        return connection;
+    }
+
+    private void unbindService(ServiceConnection service) {
+        if (service != null) {
+            mContext.unbindService(service);
+        }
+    }
+
+    @Test
+    public void onStateChangeCalled() throws Exception {
+        final LinkedBlockingQueue<Boolean> results = new LinkedBlockingQueue<>();
+        if (createCallback(mBfsccTestAppCmdService.asBinder(), results) == null) {
+            return;
+        }
+        ensureUnfrozenCallback(results);
+        freezeApp1();
+        ensureFrozenCallback(results);
+        unfreezeApp1();
+        ensureUnfrozenCallback(results);
+    }
+
+    @Test
+    public void onStateChangeNotCalledAfterCallbackRemoved() throws Exception {
+        final LinkedBlockingQueue<Boolean> results = new LinkedBlockingQueue<>();
+        IBinder.IFrozenStateChangeCallback callback;
+        if ((callback = createCallback(mBfsccTestAppCmdService.asBinder(), results)) == null) {
+            return;
+        }
+        ensureUnfrozenCallback(results);
+        mBfsccTestAppCmdService.asBinder().removeFrozenStateChangeCallback(callback);
+        freezeApp1();
+        assertEquals("No more callbacks should be invoked.", 0, results.size());
+    }
+
+    @Test
+    public void multipleCallbacks() throws Exception {
+        final LinkedBlockingQueue<Boolean> results1 = new LinkedBlockingQueue<>();
+        final LinkedBlockingQueue<Boolean> results2 = new LinkedBlockingQueue<>();
+        IBinder.IFrozenStateChangeCallback callback1;
+        if ((callback1 = createCallback(mBfsccTestAppCmdService.asBinder(), results1)) == null) {
+            return;
+        }
+        ensureUnfrozenCallback(results1);
+        freezeApp1();
+        ensureFrozenCallback(results1);
+        if (createCallback(mBfsccTestAppCmdService.asBinder(), results2) == null) {
+            return;
+        }
+        ensureFrozenCallback(results2);
+
+        unfreezeApp1();
+        ensureUnfrozenCallback(results1);
+        ensureUnfrozenCallback(results2);
+
+        mBfsccTestAppCmdService.asBinder().removeFrozenStateChangeCallback(callback1);
+        freezeApp1();
+        assertEquals("No more callbacks should be invoked.", 0, results1.size());
+        ensureFrozenCallback(results2);
+    }
+
+    @Test
+    public void onStateChangeCalledWithTheRightBinder() throws Exception {
+        final IBinder binder = mBfsccTestAppCmdService.asBinder();
+        final LinkedBlockingQueue<IBinder> results = new LinkedBlockingQueue<>();
+        IBinder.IFrozenStateChangeCallback callback =
+                (IBinder who, IBinder.IFrozenStateChangeCallback.State state) -> results.offer(who);
+        try {
+            binder.addFrozenStateChangeCallback(callback);
+        } catch (UnsupportedOperationException e) {
+            return;
+        }
+        assertEquals("Callback received the wrong Binder object.",
+                binder, results.poll(CALLBACK_WAIT_TIMEOUT_SECS, TimeUnit.SECONDS));
+        freezeApp1();
+        assertEquals("Callback received the wrong Binder object.",
+                binder, results.poll(CALLBACK_WAIT_TIMEOUT_SECS, TimeUnit.SECONDS));
+        unfreezeApp1();
+        assertEquals("Callback received the wrong Binder object.",
+                binder, results.poll(CALLBACK_WAIT_TIMEOUT_SECS, TimeUnit.SECONDS));
+    }
+
+    @After
+    public void tearDown() {
+        if (mTestAppConnection != null) {
+            mContext.unbindService(mTestAppConnection);
+        }
+    }
+
+    private IBinder.IFrozenStateChangeCallback createCallback(IBinder binder, Queue<Boolean> queue)
+            throws RemoteException {
+        try {
+            final IBinder.IFrozenStateChangeCallback callback =
+                    (IBinder who, IBinder.IFrozenStateChangeCallback.State state) ->
+                            queue.offer(state == IBinder.IFrozenStateChangeCallback.State.FROZEN);
+            binder.addFrozenStateChangeCallback(callback);
+            return callback;
+        } catch (UnsupportedOperationException e) {
+            return null;
+        }
+    }
+
+    private void ensureFrozenCallback(LinkedBlockingQueue<Boolean> queue)
+            throws InterruptedException {
+        assertEquals(Boolean.TRUE, queue.poll(CALLBACK_WAIT_TIMEOUT_SECS, TimeUnit.SECONDS));
+    }
+
+    private void ensureUnfrozenCallback(LinkedBlockingQueue<Boolean> queue)
+            throws InterruptedException {
+        assertEquals(Boolean.FALSE, queue.poll(CALLBACK_WAIT_TIMEOUT_SECS, TimeUnit.SECONDS));
+    }
+
+    private String executeShellCommand(String cmd) throws Exception {
+        return UiDevice.getInstance(
+                InstrumentationRegistry.getInstrumentation()).executeShellCommand(cmd);
+    }
+
+    private void freezeApp1() throws Exception {
+        executeShellCommand("am freeze " + TEST_PACKAGE_NAME_1);
+    }
+
+    private void freezeApp2() throws Exception {
+        executeShellCommand("am freeze " + TEST_PACKAGE_NAME_2);
+    }
+
+    private void unfreezeApp1() throws Exception {
+        executeShellCommand("am unfreeze " + TEST_PACKAGE_NAME_1);
+    }
+
+    private void unfreezeApp2() throws Exception {
+        executeShellCommand("am unfreeze " + TEST_PACKAGE_NAME_2);
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
index 499caf5..c3a5b19c94 100644
--- a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
@@ -359,7 +359,7 @@
         tracker.end(FrameTracker.REASON_END_NORMAL);
 
         // Send incomplete callback for 102L
-        sendSfFrame(tracker, 102L, JANK_NONE);
+        sendSfFrame(tracker, 4, 102L, JANK_NONE);
 
         // Send janky but complete callbck fo 103L
         sendFrame(tracker, 50, JANK_APP_DEADLINE_MISSED, 103L);
@@ -629,7 +629,7 @@
         if (!tracker.mSurfaceOnly) {
             sendHwuiFrame(tracker, durationMillis, vsyncId, firstWindowFrame);
         }
-        sendSfFrame(tracker, vsyncId, jankType);
+        sendSfFrame(tracker, durationMillis, vsyncId, jankType);
     }
 
     private void sendHwuiFrame(FrameTracker tracker, long durationMillis, long vsyncId,
@@ -645,11 +645,13 @@
         captor.getValue().run();
     }
 
-    private void sendSfFrame(FrameTracker tracker, long vsyncId, @JankType int jankType) {
+    private void sendSfFrame(
+            FrameTracker tracker, long durationMillis, long vsyncId, @JankType int jankType) {
         final ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
         doNothing().when(tracker).postCallback(captor.capture());
         mListenerCapture.getValue().onJankDataAvailable(new JankData[] {
-                new JankData(vsyncId, jankType, FRAME_TIME_60Hz)
+                new JankData(vsyncId, jankType, FRAME_TIME_60Hz, FRAME_TIME_60Hz,
+                TimeUnit.MILLISECONDS.toNanos(durationMillis))
         });
         captor.getValue().run();
     }
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java b/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java
index 66de3d7..397cdcf 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java
@@ -124,6 +124,16 @@
             return this;
         }
 
+        @Override
+        public void addFrozenStateChangeCallback(IFrozenStateChangeCallback callback)
+                throws RemoteException {
+        }
+
+        @Override
+        public boolean removeFrozenStateChangeCallback(IFrozenStateChangeCallback callback) {
+            return false;
+        }
+
         public void die() {
             isAlive = false;
             if (mRecipient != null) {
diff --git a/core/tests/hdmitests/Android.bp b/core/tests/hdmitests/Android.bp
index 5f6eaf9..e11bc55 100644
--- a/core/tests/hdmitests/Android.bp
+++ b/core/tests/hdmitests/Android.bp
@@ -37,3 +37,10 @@
     certificate: "platform",
     test_suites: ["device-tests"],
 }
+
+test_module_config {
+    name: "HdmiCecTests_hardware_hdmi",
+    base: "HdmiCecTests",
+    test_suites: ["device-tests"],
+    include_filters: ["android.hardware.hdmi"],
+}
diff --git a/core/tests/mockingcoretests/Android.bp b/core/tests/mockingcoretests/Android.bp
index aca52a8..7fd813a 100644
--- a/core/tests/mockingcoretests/Android.bp
+++ b/core/tests/mockingcoretests/Android.bp
@@ -63,3 +63,13 @@
 
     certificate: "platform",
 }
+
+test_module_config {
+    name: "FrameworksMockingCoreTests_os_bundlerecyclingtest",
+    base: "FrameworksMockingCoreTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["android.os.BundleRecyclingTest"],
+}
diff --git a/core/tests/timetests/Android.bp b/core/tests/timetests/Android.bp
index 51181a8..c33d5ee 100644
--- a/core/tests/timetests/Android.bp
+++ b/core/tests/timetests/Android.bp
@@ -23,3 +23,17 @@
     certificate: "platform",
     test_suites: ["device-tests"],
 }
+
+test_module_config {
+    name: "FrameworksTimeCoreTests_android_app",
+    base: "FrameworksTimeCoreTests",
+    test_suites: ["device-tests"],
+    include_filters: ["android.app."],
+}
+
+test_module_config {
+    name: "FrameworksTimeCoreTests_android_service",
+    base: "FrameworksTimeCoreTests",
+    test_suites: ["device-tests"],
+    include_filters: ["android.service."],
+}
diff --git a/core/tests/vibrator/src/android/os/VibrationEffectTest.java b/core/tests/vibrator/src/android/os/VibrationEffectTest.java
index 4f76dd6..f5b04ee 100644
--- a/core/tests/vibrator/src/android/os/VibrationEffectTest.java
+++ b/core/tests/vibrator/src/android/os/VibrationEffectTest.java
@@ -430,6 +430,86 @@
     }
 
     @Test
+    public void cropToLength_waveform_underLength() {
+        VibrationEffect effect = VibrationEffect.createWaveform(
+                /* timings= */ new long[]{0, 1, 2},
+                /* repeatIndex= */ -1);
+        VibrationEffect result = effect.cropToLengthOrNull(5);
+
+        assertThat(result).isEqualTo(effect); // unchanged
+    }
+
+    @Test
+    public void cropToLength_waveform_overLength() {
+        VibrationEffect effect = VibrationEffect.createWaveform(
+                /* timings= */ new long[]{0, 1, 2, 3, 4, 5, 6},
+                /* repeatIndex= */ -1);
+        VibrationEffect result = effect.cropToLengthOrNull(4);
+
+        assertThat(result).isEqualTo(VibrationEffect.createWaveform(
+                new long[]{0, 1, 2, 3},
+                -1));
+    }
+
+    @Test
+    public void cropToLength_waveform_repeating() {
+        // repeating waveforms cannot be truncated
+        VibrationEffect effect = VibrationEffect.createWaveform(
+                /* timings= */ new long[]{0, 1, 2, 3, 4, 5, 6},
+                /* repeatIndex= */ 2);
+        VibrationEffect result = effect.cropToLengthOrNull(3);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void cropToLength_waveform_withAmplitudes() {
+        VibrationEffect effect = VibrationEffect.createWaveform(
+                /* timings= */ new long[]{0, 1, 2, 3, 4, 5, 6},
+                /* amplitudes= */ new int[]{10, 20, 40, 10, 20, 40, 10},
+                /* repeatIndex= */ -1);
+        VibrationEffect result = effect.cropToLengthOrNull(3);
+
+        assertThat(result).isEqualTo(VibrationEffect.createWaveform(
+                new long[]{0, 1, 2},
+                new int[]{10, 20, 40},
+                -1));
+    }
+
+    @Test
+    public void cropToLength_composed() {
+        VibrationEffect effect = VibrationEffect.startComposition()
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK)
+                .compose();
+        VibrationEffect result = effect.cropToLengthOrNull(1);
+
+        assertThat(result).isNotNull();
+        assertThat(result).isEqualTo(VibrationEffect.startComposition()
+                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+                        .compose());
+    }
+
+    @Test
+    public void cropToLength_composed_repeating() {
+        VibrationEffect effect = VibrationEffect.startComposition()
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+                .repeatEffectIndefinitely(TEST_ONE_SHOT)
+                .compose();
+        assertThat(effect.cropToLengthOrNull(1)).isNull();
+    }
+
+    @Test
+    @RequiresFlagsEnabled(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+    public void cropToLength_vendorEffect() {
+        PersistableBundle vendorData = new PersistableBundle();
+        vendorData.putInt("key", 1);
+        VibrationEffect effect = VibrationEffect.createVendorEffect(vendorData);
+
+        assertThat(effect.cropToLengthOrNull(2)).isNull();
+    }
+
+    @Test
     public void getRingtones_noPrebakedRingtones() {
         Resources r = mockRingtoneResources(new String[0]);
         Context context = mockContext(r);
diff --git a/libs/WindowManager/Shell/AndroidManifest.xml b/libs/WindowManager/Shell/AndroidManifest.xml
index bbbc23e..3b739c3 100644
--- a/libs/WindowManager/Shell/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/AndroidManifest.xml
@@ -23,6 +23,7 @@
     <uses-permission android:name="android.permission.ROTATE_SURFACE_FLINGER" />
     <uses-permission android:name="android.permission.WAKEUP_SURFACE_FLINGER" />
     <uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
+    <uses-permission android:name="android.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE" />
 
     <application>
         <activity
diff --git a/libs/WindowManager/Shell/aconfig/multitasking.aconfig b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
index df1a98c..526ccd5 100644
--- a/libs/WindowManager/Shell/aconfig/multitasking.aconfig
+++ b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
@@ -25,11 +25,10 @@
 }
 
 flag {
-    name: "enable_pip2_implementation"
+    name: "enable_pip2"
     namespace: "multitasking"
     description: "Enables the new implementation of PiP (PiP2)"
-    bug: "290220798"
-    is_fixed_read_only: true
+    bug: "311462191"
 }
 
 flag {
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 ef679da..7b3b207 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
@@ -573,8 +573,14 @@
     private void startBackNavigation(@NonNull BackTouchTracker touchTracker) {
         try {
             startLatencyTracking();
+            final BackAnimationAdapter adapter = mEnableAnimations.get()
+                    ? mBackAnimationAdapter : null;
+            if (adapter != null && mShellBackAnimationRegistry.hasSupportedAnimatorsChanged()) {
+                adapter.updateSupportedAnimators(
+                        mShellBackAnimationRegistry.getSupportedAnimators());
+            }
             mBackNavigationInfo = mActivityTaskManager.startBackNavigation(
-                    mNavigationObserver, mEnableAnimations.get() ? mBackAnimationAdapter : null);
+                    mNavigationObserver, adapter);
             onBackNavigationInfoReceived(mBackNavigationInfo, touchTracker);
         } catch (RemoteException remoteException) {
             Log.e(TAG, "Failed to initAnimation", remoteException);
@@ -1180,16 +1186,18 @@
         }
 
         private void applyFinishOpenTransition() {
-            if (mFinishOpenTransaction != null) {
-                mFinishOpenTransaction.apply();
-                mFinishOpenTransaction = null;
-            }
-            if (mFinishOpenTransitionCallback != null) {
-                mFinishOpenTransitionCallback.onTransitionFinished(null);
-                mFinishOpenTransitionCallback = null;
-            }
             mOpenTransitionInfo = null;
             mPrepareOpenTransition = null;
+            if (mFinishOpenTransaction != null) {
+                final SurfaceControl.Transaction t = mFinishOpenTransaction;
+                mFinishOpenTransaction = null;
+                t.apply();
+            }
+            if (mFinishOpenTransitionCallback != null) {
+                final Transitions.TransitionFinishCallback callback = mFinishOpenTransitionCallback;
+                mFinishOpenTransitionCallback = null;
+                callback.onTransitionFinished(null);
+            }
         }
 
         private void applyAndFinish(@NonNull SurfaceControl.Transaction st,
@@ -1334,6 +1342,9 @@
                     tmpSize = init.getChanges().size();
                     for (int i = 0; i < tmpSize; ++i) {
                         final TransitionInfo.Change change = init.getChanges().get(i);
+                        if (change.hasFlags(FLAG_IS_WALLPAPER)) {
+                            continue;
+                        }
                         if (moveToTop) {
                             if (isSameChangeTarget(openComponent, openTaskId, openToken, change)) {
                                 change.setFlags(change.getFlags() | FLAG_MOVED_TO_TOP);
@@ -1390,6 +1401,13 @@
                 mergePendingTransitions(info);
             }
 
+            if (info.getType() == TRANSIT_CLOSE_PREPARE_BACK_NAVIGATION
+                    && !mCloseTransitionRequested && info.getChanges().isEmpty() && mApps != null) {
+                // Wait for post animation finish
+                finishCallback.onTransitionFinished(null);
+                t.apply();
+                return;
+            }
             if (isNotGestureBackTransition(info) || shouldCancelAnimation(info)
                     || !mCloseTransitionRequested) {
                 if (mPrepareOpenTransition != null) {
@@ -1497,15 +1515,28 @@
                 }
             }
             if (openingLeash != null) {
+                int rootIdx = -1;
                 for (int i = info.getChanges().size() - 1; i >= 0; --i) {
                     final TransitionInfo.Change c = info.getChanges().get(i);
+                    if (c.hasFlags(FLAG_IS_WALLPAPER)) {
+                        st.setAlpha(c.getLeash(), 1.0f);
+                        continue;
+                    }
                     if (TransitionUtil.isOpeningMode(c.getMode())) {
                         final Point offset = c.getEndRelOffset();
                         st.setPosition(c.getLeash(), offset.x, offset.y);
                         st.reparent(c.getLeash(), openingLeash);
                         st.setAlpha(c.getLeash(), 1.0f);
+                        rootIdx = TransitionUtil.rootIndexFor(c, info);
                     }
                 }
+                // The root leash and the leash of opening target should actually in the same level,
+                // but since the root leash is created after opening target, it will have higher
+                // layer in surface flinger. Move the root leash to lower level, so it won't affect
+                // the playing animation.
+                if (rootIdx >= 0 && info.getRootCount() > 0) {
+                    st.setLayer(info.getRoot(rootIdx).getLeash(), -1);
+                }
             }
             st.apply();
             mFinishOpenTransaction = ft;
@@ -1548,6 +1579,10 @@
             if (openingLeash != null && closingLeash != null) {
                 for (int i = info.getChanges().size() - 1; i >= 0; --i) {
                     final TransitionInfo.Change c = info.getChanges().get(i);
+                    if (c.hasFlags(FLAG_IS_WALLPAPER)) {
+                        st.setAlpha(c.getLeash(), 1.0f);
+                        continue;
+                    }
                     if (TransitionUtil.isOpeningMode(c.getMode())) {
                         final Point offset = c.getEndRelOffset();
                         st.setPosition(c.getLeash(), offset.x, offset.y);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java
index 6fafa75..ae2c7b3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java
@@ -23,6 +23,8 @@
 import android.util.SparseArray;
 import android.window.BackNavigationInfo;
 
+import java.util.ArrayList;
+
 /** Registry for all types of default back animations */
 public class ShellBackAnimationRegistry {
     private static final String TAG = "ShellBackPreview";
@@ -31,6 +33,8 @@
     private ShellBackAnimation mDefaultCrossActivityAnimation;
     private final ShellBackAnimation mCustomizeActivityAnimation;
     private final ShellBackAnimation mCrossTaskAnimation;
+    private boolean mSupportedAnimatorsChanged = false;
+    private final ArrayList<Integer> mSupportedAnimators = new ArrayList<>();
 
     public ShellBackAnimationRegistry(
             @ShellBackAnimation.CrossActivity @Nullable ShellBackAnimation crossActivityAnimation,
@@ -60,7 +64,7 @@
         mDefaultCrossActivityAnimation = crossActivityAnimation;
         mCustomizeActivityAnimation = customizeActivityAnimation;
         mCrossTaskAnimation = crossTaskAnimation;
-
+        updateSupportedAnimators();
         // TODO(b/236760237): register dialog close animation when it's completed.
     }
 
@@ -71,6 +75,7 @@
         if (BackNavigationInfo.TYPE_CROSS_ACTIVITY == type) {
             mDefaultCrossActivityAnimation = null;
         }
+        updateSupportedAnimators();
     }
 
     void unregisterAnimation(@BackNavigationInfo.BackTargetType int type) {
@@ -79,6 +84,24 @@
         if (BackNavigationInfo.TYPE_CROSS_ACTIVITY == type) {
             mDefaultCrossActivityAnimation = null;
         }
+        updateSupportedAnimators();
+    }
+
+    private void updateSupportedAnimators() {
+        mSupportedAnimators.clear();
+        for (int i = mAnimationDefinition.size() - 1; i >= 0; --i) {
+            mSupportedAnimators.add(mAnimationDefinition.keyAt(i));
+        }
+        mSupportedAnimatorsChanged = true;
+    }
+
+    boolean hasSupportedAnimatorsChanged() {
+        return mSupportedAnimatorsChanged;
+    }
+
+    ArrayList<Integer> getSupportedAnimators() {
+        mSupportedAnimatorsChanged = false;
+        return mSupportedAnimators;
     }
 
     /**
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 5b01a0d..f03daad 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
@@ -291,17 +291,11 @@
             if (hadImeSourceControl != hasImeSourceControl) {
                 dispatchImeControlTargetChanged(mDisplayId, hasImeSourceControl);
             }
+            final boolean hasImeLeash = hasImeSourceControl && imeSourceControl.getLeash() != null;
 
             boolean pendingImeStartAnimation = false;
-            boolean canAnimate;
-            if (android.view.inputmethod.Flags.refactorInsetsController()) {
-                canAnimate = hasImeSourceControl && imeSourceControl.getLeash() != null;
-            } else {
-                canAnimate = hasImeSourceControl;
-            }
-
             boolean positionChanged = false;
-            if (canAnimate) {
+            if (hasImeLeash) {
                 if (mAnimation != null) {
                     final Point lastSurfacePosition = hadImeSourceControl
                             ? mImeSourceControl.getSurfacePosition() : null;
@@ -325,6 +319,13 @@
                 // continue the bar to slide to the end (even without visible IME)
                 mAnimation.cancel();
             }
+
+            // Make mImeSourceControl point to the new control before starting the animation.
+            if (hadImeSourceControl && mImeSourceControl != imeSourceControl) {
+                mImeSourceControl.release(SurfaceControl::release);
+            }
+            mImeSourceControl = imeSourceControl;
+
             if (positionChanged) {
                 if (android.view.inputmethod.Flags.refactorInsetsController()) {
                     // For showing the IME, the leash has to be available first. Hiding
@@ -338,11 +339,6 @@
                 }
             }
 
-            if (hadImeSourceControl && mImeSourceControl != imeSourceControl) {
-                mImeSourceControl.release(SurfaceControl::release);
-            }
-            mImeSourceControl = imeSourceControl;
-
             if (android.view.inputmethod.Flags.refactorInsetsController()) {
                 if (pendingImeStartAnimation) {
                     startAnimation(true, true /* forceRestart */);
@@ -465,11 +461,12 @@
 
         private void startAnimation(final boolean show, final boolean forceRestart,
                 @NonNull final ImeTracker.Token statsToken) {
+            if (mImeSourceControl == null || mImeSourceControl.getLeash() == null) {
+                if (DEBUG) Slog.d(TAG, "No leash available, not starting the animation.");
+                return;
+            }
             if (android.view.inputmethod.Flags.refactorInsetsController()) {
-                if (mImeSourceControl == null || mImeSourceControl.getLeash() == null) {
-                    if (DEBUG) Slog.d(TAG, "No leash available, not starting the animation.");
-                    return;
-                } else if (!mImeRequestedVisible && show) {
+                if (!mImeRequestedVisible && show) {
                     // we have a control with leash, but the IME was not requested visible before,
                     // therefore aborting the show animation.
                     Slog.e(TAG, "IME was not requested visible, not starting the show animation.");
@@ -478,7 +475,7 @@
                 }
             }
             final InsetsSource imeSource = mInsetsState.peekSource(InsetsSource.ID_IME);
-            if (imeSource == null || mImeSourceControl == null) {
+            if (imeSource == null) {
                 ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_WM_ANIMATION_CREATE);
                 return;
             }
@@ -515,8 +512,10 @@
                 }
                 mAnimation.cancel();
             }
-            final float defaultY = mImeSourceControl.getSurfacePosition().y;
-            final float x = mImeSourceControl.getSurfacePosition().x;
+            final InsetsSourceControl animatingControl = new InsetsSourceControl(mImeSourceControl);
+            final SurfaceControl animatingLeash = animatingControl.getLeash();
+            final float defaultY = animatingControl.getSurfacePosition().y;
+            final float x = animatingControl.getSurfacePosition().x;
             final float hiddenY = defaultY + mImeFrame.height();
             final float shownY = defaultY;
             final float startY = show ? hiddenY : shownY;
@@ -538,13 +537,10 @@
             mAnimation.addUpdateListener(animation -> {
                 SurfaceControl.Transaction t = mTransactionPool.acquire();
                 float value = (float) animation.getAnimatedValue();
-                if (!android.view.inputmethod.Flags.refactorInsetsController() || (
-                        mImeSourceControl != null && mImeSourceControl.getLeash() != null)) {
-                    t.setPosition(mImeSourceControl.getLeash(), x, value);
-                    final float alpha = (mAnimateAlpha || isFloating)
-                            ? (value - hiddenY) / (shownY - hiddenY) : 1.f;
-                    t.setAlpha(mImeSourceControl.getLeash(), alpha);
-                }
+                t.setPosition(animatingLeash, x, value);
+                final float alpha = (mAnimateAlpha || isFloating)
+                        ? (value - hiddenY) / (shownY - hiddenY) : 1f;
+                t.setAlpha(animatingLeash, alpha);
                 dispatchPositionChanged(mDisplayId, imeTop(value), t);
                 t.apply();
                 mTransactionPool.release(t);
@@ -561,7 +557,7 @@
                     ValueAnimator valueAnimator = (ValueAnimator) animation;
                     float value = (float) valueAnimator.getAnimatedValue();
                     SurfaceControl.Transaction t = mTransactionPool.acquire();
-                    t.setPosition(mImeSourceControl.getLeash(), x, value);
+                    t.setPosition(animatingLeash, x, value);
                     if (DEBUG) {
                         Slog.d(TAG, "onAnimationStart d:" + mDisplayId + " top:"
                                 + imeTop(hiddenY) + "->" + imeTop(shownY)
@@ -573,19 +569,19 @@
                     final float alpha = (mAnimateAlpha || isFloating)
                             ? (value - hiddenY) / (shownY - hiddenY)
                             : 1.f;
-                    t.setAlpha(mImeSourceControl.getLeash(), alpha);
+                    t.setAlpha(animatingLeash, alpha);
                     if (mAnimationDirection == DIRECTION_SHOW) {
                         ImeTracker.forLogging().onProgress(mStatsToken,
                                 ImeTracker.PHASE_WM_ANIMATION_RUNNING);
-                        t.show(mImeSourceControl.getLeash());
+                        t.show(animatingLeash);
                     }
                     if (DEBUG_IME_VISIBILITY) {
                         EventLog.writeEvent(IMF_IME_REMOTE_ANIM_START,
                                 mStatsToken != null ? mStatsToken.getTag() : ImeTracker.TOKEN_NONE,
                                 mDisplayId, mAnimationDirection, alpha, value, endY,
-                                Objects.toString(mImeSourceControl.getLeash()),
-                                Objects.toString(mImeSourceControl.getInsetsHint()),
-                                Objects.toString(mImeSourceControl.getSurfacePosition()),
+                                Objects.toString(animatingLeash),
+                                Objects.toString(animatingControl.getInsetsHint()),
+                                Objects.toString(animatingControl.getSurfacePosition()),
                                 Objects.toString(mImeFrame));
                     }
                     t.apply();
@@ -599,31 +595,23 @@
                         EventLog.writeEvent(IMF_IME_REMOTE_ANIM_CANCEL,
                                 mStatsToken != null ? mStatsToken.getTag() : ImeTracker.TOKEN_NONE,
                                 mDisplayId,
-                                Objects.toString(mImeSourceControl.getInsetsHint()));
+                                Objects.toString(animatingControl.getInsetsHint()));
                     }
                 }
 
                 @Override
                 public void onAnimationEnd(Animator animation) {
-                    boolean hasLeash =
-                            mImeSourceControl != null && mImeSourceControl.getLeash() != null;
                     if (DEBUG) Slog.d(TAG, "onAnimationEnd " + mCancelled);
                     SurfaceControl.Transaction t = mTransactionPool.acquire();
                     if (!mCancelled) {
-                        if (!android.view.inputmethod.Flags.refactorInsetsController()
-                                || hasLeash) {
-                            t.setPosition(mImeSourceControl.getLeash(), x, endY);
-                            t.setAlpha(mImeSourceControl.getLeash(), 1.f);
-                        }
+                        t.setPosition(animatingLeash, x, endY);
+                        t.setAlpha(animatingLeash, 1.f);
                     }
                     dispatchEndPositioning(mDisplayId, mCancelled, t);
                     if (mAnimationDirection == DIRECTION_HIDE && !mCancelled) {
                         ImeTracker.forLogging().onProgress(mStatsToken,
                                 ImeTracker.PHASE_WM_ANIMATION_RUNNING);
-                        if (!android.view.inputmethod.Flags.refactorInsetsController()
-                                || hasLeash) {
-                            t.hide(mImeSourceControl.getLeash());
-                        }
+                        t.hide(animatingLeash);
                         removeImeSurface(mDisplayId);
                         ImeTracker.forLogging().onHidden(mStatsToken);
                     } else if (mAnimationDirection == DIRECTION_SHOW && !mCancelled) {
@@ -636,13 +624,9 @@
                         EventLog.writeEvent(IMF_IME_REMOTE_ANIM_END,
                                 mStatsToken != null ? mStatsToken.getTag() : ImeTracker.TOKEN_NONE,
                                 mDisplayId, mAnimationDirection, endY,
-                                Objects.toString(
-                                        mImeSourceControl != null ? mImeSourceControl.getLeash()
-                                                : "null"),
-                                Objects.toString(mImeSourceControl != null
-                                        ? mImeSourceControl.getInsetsHint() : "null"),
-                                Objects.toString(mImeSourceControl != null
-                                        ? mImeSourceControl.getSurfacePosition() : "null"),
+                                Objects.toString(animatingLeash),
+                                Objects.toString(animatingControl.getInsetsHint()),
+                                Objects.toString(animatingControl.getSurfacePosition()),
                                 Objects.toString(mImeFrame));
                     }
                     t.apply();
@@ -650,6 +634,7 @@
 
                     mAnimationDirection = DIRECTION_NONE;
                     mAnimation = null;
+                    animatingControl.release(SurfaceControl::release);
                 }
             });
             if (!show) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
index dcf84d9..7070ce9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
@@ -24,7 +24,6 @@
 import android.content.pm.PackageManager
 import android.graphics.Rect
 import android.os.RemoteException
-import android.os.SystemProperties
 import android.util.DisplayMetrics
 import android.util.Log
 import android.util.Pair
@@ -178,9 +177,7 @@
                 "org.chromium.arc", 0)
             val isTv = AppGlobals.getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_LEANBACK, 0)
-            isPip2ExperimentEnabled = SystemProperties.getBoolean(
-                    "persist.wm_shell.pip2", false) ||
-                    (Flags.enablePip2Implementation() && !isArc && !isTv)
+            isPip2ExperimentEnabled = Flags.enablePip2() && !isArc && !isTv
         }
         return isPip2ExperimentEnabled as Boolean
     }
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 972b78f..6146ecd 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
@@ -831,7 +831,6 @@
      */
     static class CompatUIHintsState {
         boolean mHasShownSizeCompatHint;
-        boolean mHasShownCameraCompatHint;
         boolean mHasShownUserAspectRatioSettingsButtonHint;
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index 39bea1b..9af33a8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -21,9 +21,12 @@
 
 import static com.android.wm.shell.shared.ShellSharedConstants.KEY_EXTRA_SHELL_RECENT_TASKS;
 
+import android.Manifest;
+import android.annotation.RequiresPermission;
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.app.IApplicationThread;
+import android.app.KeyguardManager;
 import android.app.PendingIntent;
 import android.content.ComponentName;
 import android.content.Context;
@@ -158,6 +161,7 @@
         return new IRecentTasksImpl(this);
     }
 
+    @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
     private void onInit() {
         mShellController.addExternalInterface(KEY_EXTRA_SHELL_RECENT_TASKS,
                 this::createExternalInterface, this);
@@ -168,6 +172,8 @@
             mTaskStackTransitionObserver.addTaskStackTransitionObserverListener(this,
                     mMainExecutor);
         }
+        mContext.getSystemService(KeyguardManager.class).addKeyguardLockedStateListener(
+                mMainExecutor, isKeyguardLocked -> notifyRecentTasksChanged());
     }
 
     void setTransitionHandler(RecentsTransitionHandler handler) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
index 1cbb8bb..1dad413 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
@@ -33,7 +33,7 @@
 
 /**
  * Main stage for split-screen mode. When split-screen is active all standard activity types launch
- * on the main stage, except for task that are explicitly pinned to the {@link SideStage}.
+ * on the main stage, except for task that are explicitly pinned to the {@link StageTaskListener}.
  * @see StageCoordinator
  */
 class MainStage extends StageTaskListener {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
deleted file mode 100644
index 27fd309..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.splitscreen;
-
-import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.view.SurfaceSession;
-import android.window.WindowContainerToken;
-import android.window.WindowContainerTransaction;
-
-import com.android.internal.protolog.ProtoLog;
-import com.android.launcher3.icons.IconProvider;
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.windowdecor.WindowDecorViewModel;
-
-import java.util.Optional;
-
-/**
- * Side stage for split-screen mode. Only tasks that are explicitly pinned to this stage show up
- * here. All other task are launch in the {@link MainStage}.
- *
- * @see StageCoordinator
- */
-class SideStage extends StageTaskListener {
-    private static final String TAG = SideStage.class.getSimpleName();
-
-    SideStage(Context context, ShellTaskOrganizer taskOrganizer, int displayId,
-            StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
-            SurfaceSession surfaceSession, IconProvider iconProvider,
-            Optional<WindowDecorViewModel> windowDecorViewModel) {
-        super(context, taskOrganizer, displayId, callbacks, syncQueue, surfaceSession,
-                iconProvider, windowDecorViewModel);
-    }
-
-    boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) {
-        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "remove all side stage tasks: childCount=%d toTop=%b",
-                mChildrenTaskInfo.size(), toTop);
-        if (mChildrenTaskInfo.size() == 0) return false;
-        wct.reparentTasks(
-                mRootTaskInfo.token,
-                null /* newParent */,
-                null /* windowingModes */,
-                null /* activityTypes */,
-                toTop);
-        return true;
-    }
-
-    boolean removeTask(int taskId, WindowContainerToken newParent, WindowContainerTransaction wct) {
-        final ActivityManager.RunningTaskInfo task = mChildrenTaskInfo.get(taskId);
-        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "remove side stage task: task=%d exists=%b", taskId,
-                task != null);
-        if (task == null) return false;
-        wct.reparent(task.token, newParent, false /* onTop */);
-        return true;
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
index a6233dc9..526c1d4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
@@ -50,7 +50,7 @@
 
     /**
      * The side stage type.
-     * @see SideStage
+     * @see StageTaskListener
      */
     int STAGE_TYPE_SIDE = 1;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java
index cea995d..1e6fa28 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java
@@ -32,6 +32,7 @@
 import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__SCREEN_LOCKED;
 import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__SCREEN_LOCKED_SHOW_ON_TOP;
 import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__UNKNOWN_EXIT;
+import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
 import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
 import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASON_DRAG;
@@ -57,6 +58,7 @@
 
 import com.android.internal.logging.InstanceId;
 import com.android.internal.logging.InstanceIdSequence;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.wm.shell.shared.split.SplitScreenConstants.SplitPosition;
 import com.android.wm.shell.splitscreen.SplitScreenController.ExitReason;
@@ -133,6 +135,11 @@
             @SplitPosition int mainStagePosition, int mainStageUid,
             @SplitPosition int sideStagePosition, int sideStageUid,
             boolean isLandscape) {
+        if (hasStartedSession()) {
+            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "logEnter: no-op, previous session has not ended");
+            return;
+        }
+
         mLoggerSessionId = mIdSequence.newInstanceId();
         int enterReason = getLoggerEnterReason(isLandscape);
         updateMainStageState(getMainStagePositionFromSplitPosition(mainStagePosition, isLandscape),
@@ -140,6 +147,14 @@
         updateSideStageState(getSideStagePositionFromSplitPosition(sideStagePosition, isLandscape),
                 sideStageUid);
         updateSplitRatioState(splitRatio);
+
+        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "logEnter: enterReason=%d splitRatio=%f "
+                        + "mainStagePosition=%d mainStageUid=%d sideStagePosition=%d "
+                        + "sideStageUid=%d isLandscape=%b mEnterSessionId=%d mLoggerSessionId=%d",
+                enterReason, splitRatio, mLastMainStagePosition, mLastMainStageUid,
+                mLastSideStagePosition, mLastSideStageUid, isLandscape,
+                mEnterSessionId != null ? mEnterSessionId.getId() : 0, mLoggerSessionId.getId());
+
         FrameworkStatsLog.write(FrameworkStatsLog.SPLITSCREEN_UI_CHANGED,
                 FrameworkStatsLog.SPLITSCREEN_UICHANGED__ACTION__ENTER,
                 enterReason,
@@ -212,14 +227,25 @@
             @SplitPosition int mainStagePosition, int mainStageUid,
             @SplitPosition int sideStagePosition, int sideStageUid, boolean isLandscape) {
         if (mLoggerSessionId == null) {
+            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "logExit: no-op, mLoggerSessionId is null");
             // Ignore changes until we've started logging the session
             return;
         }
         if ((mainStagePosition != SPLIT_POSITION_UNDEFINED
                 && sideStagePosition != SPLIT_POSITION_UNDEFINED)
                         || (mainStageUid != 0 && sideStageUid != 0)) {
+            ProtoLog.d(WM_SHELL_SPLIT_SCREEN,
+                    "logExit: no-op, only main or side stage should be set, not both/none");
             throw new IllegalArgumentException("Only main or side stage should be set");
         }
+
+        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "logExit: exitReason=%d mainStagePosition=%d"
+                        + " mainStageUid=%d sideStagePosition=%d sideStageUid=%d isLandscape=%b"
+                        + " mLoggerSessionId=%d", getLoggerExitReason(exitReason),
+                getMainStagePositionFromSplitPosition(mainStagePosition, isLandscape), mainStageUid,
+                getSideStagePositionFromSplitPosition(sideStagePosition, isLandscape), sideStageUid,
+                isLandscape, mLoggerSessionId.getId());
+
         FrameworkStatsLog.write(FrameworkStatsLog.SPLITSCREEN_UI_CHANGED,
                 FrameworkStatsLog.SPLITSCREEN_UICHANGED__ACTION__EXIT,
                 0 /* enterReason */,
@@ -304,18 +330,25 @@
      */
     public void logResize(float splitRatio) {
         if (mLoggerSessionId == null) {
+            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "logResize: no-op, mLoggerSessionId is null");
             // Ignore changes until we've started logging the session
             return;
         }
         if (splitRatio <= 0f || splitRatio >= 1f) {
+            ProtoLog.d(WM_SHELL_SPLIT_SCREEN,
+                    "logResize: no-op, splitRatio indicates that user is dismissing, not resizing");
             // Don't bother reporting resizes that end up dismissing the split, that will be logged
             // via the exit event
             return;
         }
         if (!updateSplitRatioState(splitRatio)) {
+            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "logResize: no-op, split ratio was not changed");
             // Ignore if there are no user perceived changes
             return;
         }
+
+        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "logResize: splitRatio=%f mLoggerSessionId=%d",
+                mLastSplitRatio, mLoggerSessionId.getId());
         FrameworkStatsLog.write(FrameworkStatsLog.SPLITSCREEN_UI_CHANGED,
                 FrameworkStatsLog.SPLITSCREEN_UICHANGED__ACTION__RESIZE,
                 0 /* enterReason */,
@@ -335,6 +368,7 @@
     public void logSwap(@SplitPosition int mainStagePosition, int mainStageUid,
             @SplitPosition int sideStagePosition, int sideStageUid, boolean isLandscape) {
         if (mLoggerSessionId == null) {
+            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "logSwap: no-op, mLoggerSessionId is null");
             // Ignore changes until we've started logging the session
             return;
         }
@@ -343,6 +377,11 @@
                 mainStageUid);
         updateSideStageState(getSideStagePositionFromSplitPosition(sideStagePosition, isLandscape),
                 sideStageUid);
+
+        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "logSwap: mainStagePosition=%d mainStageUid=%d "
+                + "sideStagePosition=%d sideStageUid=%d mLoggerSessionId=%d",
+                mLastMainStagePosition, mLastMainStageUid, mLastSideStagePosition,
+                mLastSideStageUid, mLoggerSessionId.getId());
         FrameworkStatsLog.write(FrameworkStatsLog.SPLITSCREEN_UI_CHANGED,
                 FrameworkStatsLog.SPLITSCREEN_UICHANGED__ACTION__SWAP,
                 0 /* enterReason */,
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 8921ceb..f3959cc 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
@@ -155,13 +155,13 @@
 
 /**
  * Coordinates the staging (visibility, sizing, ...) of the split-screen {@link MainStage} and
- * {@link SideStage} stages.
+ * other stages.
  * Some high-level rules:
- * - The {@link StageCoordinator} is only considered active if the {@link SideStage} contains at
+ * - The {@link StageCoordinator} is only considered active if the other stages contain at
  * least one child task.
  * - The {@link MainStage} should only have children if the coordinator is active.
  * - The {@link SplitLayout} divider is only visible if both the {@link MainStage}
- * and {@link SideStage} are visible.
+ * and other stages are visible.
  * - Both stages are put under a single-top root task.
  * This rules are mostly implemented in {@link #onStageVisibilityChanged(StageListenerImpl)} and
  * {@link #onStageHasChildrenChanged(StageListenerImpl).}
@@ -176,7 +176,7 @@
 
     private final MainStage mMainStage;
     private final StageListenerImpl mMainStageListener = new StageListenerImpl();
-    private final SideStage mSideStage;
+    private final StageTaskListener mSideStage;
     private final StageListenerImpl mSideStageListener = new StageListenerImpl();
     @SplitPosition
     private int mSideStagePosition = SPLIT_POSITION_BOTTOM_OR_RIGHT;
@@ -338,7 +338,7 @@
                 mSurfaceSession,
                 iconProvider,
                 mWindowDecorViewModel);
-        mSideStage = new SideStage(
+        mSideStage = new StageTaskListener(
                 mContext,
                 mTaskOrganizer,
                 mDisplayId,
@@ -367,7 +367,7 @@
 
     @VisibleForTesting
     StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
-            ShellTaskOrganizer taskOrganizer, MainStage mainStage, SideStage sideStage,
+            ShellTaskOrganizer taskOrganizer, MainStage mainStage, StageTaskListener sideStage,
             DisplayController displayController, DisplayImeController displayImeController,
             DisplayInsetsController displayInsetsController, SplitLayout splitLayout,
             Transitions transitions, TransactionPool transactionPool, ShellExecutor mainExecutor,
@@ -424,6 +424,15 @@
         return mMainStage.isActive();
     }
 
+    /**
+     * Deactivates main stage by removing the stage from the top level split root (usually when a
+     * task underneath gets removed from the stage root).
+     * @param reparentToTop whether we want to put the stage root back on top
+     */
+    private void deactivateSplit(WindowContainerTransaction wct, boolean reparentToTop) {
+        mMainStage.deactivate(wct, reparentToTop);
+    }
+
     /** @return whether this transition-request has the launch-adjacent flag. */
     public boolean requestHasLaunchAdjacentFlag(TransitionRequestInfo request) {
         final ActivityManager.RunningTaskInfo triggerTask = request.getTriggerTask();
@@ -498,10 +507,10 @@
 
         /**
          * {@link MainStage} will be deactivated in {@link #onStageHasChildrenChanged} if the
-         * {@link SideStage} no longer has children.
+         * other stages no longer have children.
          */
         final boolean result = mSideStage.removeTask(taskId,
-                mMainStage.isActive() ? mMainStage.mRootTaskInfo.token : null,
+                isSplitActive() ? mMainStage.mRootTaskInfo.token : null,
                 wct);
         mTaskOrganizer.applyTransaction(wct);
         return result;
@@ -618,7 +627,7 @@
         }
 
         // If split screen is not activated, we're expecting to open a pair of apps to split.
-        final int extraTransitType = mMainStage.isActive()
+        final int extraTransitType = isSplitActive()
                 ? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
         prepareEnterSplitScreen(wct, null /* taskInfo */, position, !mIsDropEntering);
 
@@ -661,7 +670,7 @@
         }
 
         // If split screen is not activated, we're expecting to open a pair of apps to split.
-        final int extraTransitType = mMainStage.isActive()
+        final int extraTransitType = isSplitActive()
                 ? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
         prepareEnterSplitScreen(wct, null /* taskInfo */, position, !mIsDropEntering);
 
@@ -793,7 +802,7 @@
     private void startWithTask(WindowContainerTransaction wct, int mainTaskId,
             @Nullable Bundle mainOptions, @PersistentSnapPosition int snapPosition,
             @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
-        if (!mMainStage.isActive()) {
+        if (!isSplitActive()) {
             // Build a request WCT that will launch both apps such that task 0 is on the main stage
             // while task 1 is on the side stage.
             mMainStage.activate(wct, false /* reparent */);
@@ -860,7 +869,7 @@
             return;
         }
 
-        if (!mMainStage.isActive()) {
+        if (!isSplitActive()) {
             // Build a request WCT that will launch both apps such that task 0 is on the main stage
             // while task 1 is on the side stage.
             mMainStage.activate(wct, false /* reparent */);
@@ -1110,7 +1119,7 @@
      */
     void onKeyguardStateChanged(boolean active, boolean occludingTaskRunning) {
         mKeyguardActive = active;
-        if (!mMainStage.isActive()) {
+        if (!isSplitActive()) {
             return;
         }
         ProtoLog.d(WM_SHELL_SPLIT_SCREEN,
@@ -1154,7 +1163,7 @@
      * will do a no-op.
      */
     void dismissSplitKeepingLastActiveStage(@ExitReason int reason) {
-        if (!mMainStage.isActive() || mLastActiveStage == STAGE_TYPE_UNDEFINED) {
+        if (!isSplitActive() || mLastActiveStage == STAGE_TYPE_UNDEFINED) {
             // no-op
             return;
         }
@@ -1177,8 +1186,8 @@
     private void exitSplitScreen(@Nullable StageTaskListener childrenToTop,
             @ExitReason int exitReason) {
         ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "exitSplitScreen: mainStageToTop=%b reason=%s active=%b",
-                childrenToTop == mMainStage, exitReasonToString(exitReason), mMainStage.isActive());
-        if (!mMainStage.isActive()) return;
+                childrenToTop == mMainStage, exitReasonToString(exitReason), isSplitActive());
+        if (!isSplitActive()) return;
 
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         applyExitSplitScreen(childrenToTop, wct, exitReason);
@@ -1188,7 +1197,7 @@
             WindowContainerTransaction wct, @ExitReason int exitReason) {
         ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "applyExitSplitScreen: reason=%s",
                 exitReasonToString(exitReason));
-        if (!mMainStage.isActive() || mIsExiting) return;
+        if (!isSplitActive() || mIsExiting) return;
 
         onSplitScreenExit();
         clearSplitPairedInRecents(exitReason);
@@ -1200,7 +1209,7 @@
         mSplitLayout.getInvisibleBounds(mTempRect1);
         if (childrenToTop == null || childrenToTop.getTopVisibleChildTaskId() == INVALID_TASK_ID) {
             mSideStage.removeAllTasks(wct, false /* toTop */);
-            mMainStage.deactivate(wct, false /* toTop */);
+            deactivateSplit(wct, false /* reparentToTop */);
             wct.reorder(mRootTaskInfo.token, false /* onTop */);
             setRootForceTranslucent(true, wct);
             wct.setBounds(mSideStage.mRootTaskInfo.token, mTempRect1);
@@ -1229,7 +1238,7 @@
                 childrenToTop.fadeOutDecor(() -> {
                     WindowContainerTransaction finishedWCT = new WindowContainerTransaction();
                     mIsExiting = false;
-                    mMainStage.deactivate(finishedWCT, childrenToTop == mMainStage /* toTop */);
+                    deactivateSplit(finishedWCT, childrenToTop == mMainStage /* reparentToTop */);
                     mSideStage.removeAllTasks(finishedWCT, childrenToTop == mSideStage /* toTop */);
                     finishedWCT.reorder(mRootTaskInfo.token, false /* toTop */);
                     setRootForceTranslucent(true, finishedWCT);
@@ -1252,7 +1261,7 @@
     }
 
     void dismissSplitScreen(int toTopTaskId, @ExitReason int exitReason) {
-        if (!mMainStage.isActive()) return;
+        if (!isSplitActive()) return;
         final int stage = getStageOfTask(toTopTaskId);
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         prepareExitSplitScreen(stage, wct);
@@ -1362,10 +1371,10 @@
      */
     void prepareExitSplitScreen(@StageType int stageToTop,
             @NonNull WindowContainerTransaction wct) {
-        if (!mMainStage.isActive()) return;
+        if (!isSplitActive()) return;
         ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "prepareExitSplitScreen: stageToTop=%d", stageToTop);
         mSideStage.removeAllTasks(wct, stageToTop == STAGE_TYPE_SIDE);
-        mMainStage.deactivate(wct, stageToTop == STAGE_TYPE_MAIN);
+        deactivateSplit(wct, stageToTop == STAGE_TYPE_MAIN);
     }
 
     private void prepareEnterSplitScreen(WindowContainerTransaction wct) {
@@ -1471,12 +1480,11 @@
         mSkipEvictingMainStageChildren = false;
         mSplitRequest = null;
         updateRecentTasksSplitPair();
-        if (!mLogger.hasStartedSession()) {
-            mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(),
-                    getMainStagePosition(), mMainStage.getTopChildTaskUid(),
-                    getSideStagePosition(), mSideStage.getTopChildTaskUid(),
-                    mSplitLayout.isLeftRightSplit());
-        }
+
+        mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(),
+                getMainStagePosition(), mMainStage.getTopChildTaskUid(),
+                getSideStagePosition(), mSideStage.getTopChildTaskUid(),
+                mSplitLayout.isLeftRightSplit());
     }
 
     void getStageBounds(Rect outTopOrLeftBounds, Rect outBottomOrRightBounds) {
@@ -1662,7 +1670,7 @@
         mRootTaskInfo = taskInfo;
         if (mSplitLayout != null
                 && mSplitLayout.updateConfiguration(mRootTaskInfo.configuration)
-                && mMainStage.isActive()) {
+                && isSplitActive()) {
             ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTaskInfoChanged: task=%d updating",
                     taskInfo.taskId);
             // Clear the divider remote animating flag as the divider will be re-rendered to apply
@@ -1916,7 +1924,7 @@
                 stageListener == mMainStageListener);
         final boolean hasChildren = stageListener.mHasChildren;
         final boolean isSideStage = stageListener == mSideStageListener;
-        if (!hasChildren && !mIsExiting && mMainStage.isActive()) {
+        if (!hasChildren && !mIsExiting && isSplitActive()) {
             if (isSideStage && mMainStageListener.mVisible) {
                 // Exit to main stage if side stage no longer has children.
                 mSplitLayout.flingDividerToDismiss(
@@ -1931,7 +1939,7 @@
                 // Dismiss split screen in the background once any sides of the split become empty.
                 exitSplitScreen(null /* childrenToTop */, EXIT_REASON_APP_FINISHED);
             }
-        } else if (isSideStage && hasChildren && !mMainStage.isActive()) {
+        } else if (isSideStage && hasChildren && !isSplitActive()) {
             final WindowContainerTransaction wct = new WindowContainerTransaction();
             prepareEnterSplitScreen(wct);
 
@@ -1952,15 +1960,13 @@
             clearRequestIfPresented();
             updateRecentTasksSplitPair();
 
-            if (!mLogger.hasStartedSession()) {
-                if (!mLogger.hasValidEnterSessionId()) {
-                    mLogger.enterRequested(null /*enterSessionId*/, ENTER_REASON_MULTI_INSTANCE);
-                }
-                mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(),
-                        getMainStagePosition(), mMainStage.getTopChildTaskUid(),
-                        getSideStagePosition(), mSideStage.getTopChildTaskUid(),
-                        mSplitLayout.isLeftRightSplit());
+            if (!mLogger.hasStartedSession() && !mLogger.hasValidEnterSessionId()) {
+                mLogger.enterRequested(null /*enterSessionId*/, ENTER_REASON_MULTI_INSTANCE);
             }
+            mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(),
+                    getMainStagePosition(), mMainStage.getTopChildTaskUid(),
+                    getSideStagePosition(), mSideStage.getTopChildTaskUid(),
+                    mSplitLayout.isLeftRightSplit());
         }
     }
 
@@ -2146,7 +2152,7 @@
 
     private void onDisplayChange(int displayId, int fromRotation, int toRotation,
             @Nullable DisplayAreaInfo newDisplayAreaInfo, WindowContainerTransaction wct) {
-        if (displayId != DEFAULT_DISPLAY || !mMainStage.isActive()) {
+        if (displayId != DEFAULT_DISPLAY || !isSplitActive()) {
             return;
         }
 
@@ -2441,7 +2447,7 @@
             // Not entering or exiting, so just do some house-keeping and validation.
 
             // If we're not in split-mode, just abort so something else can handle it.
-            if (!mMainStage.isActive()) return false;
+            if (!isSplitActive()) return false;
 
             ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "startAnimation: transition=%d", info.getDebugId());
             mSplitLayout.setFreezeDividerWindow(false);
@@ -2683,7 +2689,7 @@
     public void onTransitionAnimationComplete() {
         ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTransitionAnimationComplete");
         // If still playing, let it finish.
-        if (!mMainStage.isActive() && !mIsExiting) {
+        if (!isSplitActive() && !mIsExiting) {
             // Update divider state after animation so that it is still around and positioned
             // properly for the animation itself.
             mSplitLayout.release();
@@ -3147,7 +3153,7 @@
                 + (mSplitLayout != null ? mSplitLayout.isLeftRightSplit() : "null"));
         pw.println(innerPrefix + "MainStage");
         pw.println(childPrefix + "stagePosition=" + splitPositionToString(getMainStagePosition()));
-        pw.println(childPrefix + "isActive=" + mMainStage.isActive());
+        pw.println(childPrefix + "isActive=" + isSplitActive());
         mMainStage.dump(pw, childPrefix);
         pw.println(innerPrefix + "MainStageListener");
         mMainStageListener.dump(pw, childPrefix);
@@ -3267,7 +3273,7 @@
         @Override
         public void onNoLongerSupportMultiWindow(ActivityManager.RunningTaskInfo taskInfo) {
             ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onNoLongerSupportMultiWindow: task=%s", taskInfo);
-            if (mMainStage.isActive()) {
+            if (isSplitActive()) {
                 final boolean isMainStage = mMainStageListener == this;
 
                 // If visible, we preserve the app and keep it running. If an app becomes
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 99f3832..4593553 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
@@ -475,6 +475,30 @@
         });
     }
 
+    // --------
+    // Previously only used in SideStage
+    boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) {
+        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "remove all side stage tasks: childCount=%d toTop=%b",
+                mChildrenTaskInfo.size(), toTop);
+        if (mChildrenTaskInfo.size() == 0) return false;
+        wct.reparentTasks(
+                mRootTaskInfo.token,
+                null /* newParent */,
+                null /* windowingModes */,
+                null /* activityTypes */,
+                toTop);
+        return true;
+    }
+
+    boolean removeTask(int taskId, WindowContainerToken newParent, WindowContainerTransaction wct) {
+        final ActivityManager.RunningTaskInfo task = mChildrenTaskInfo.get(taskId);
+        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "remove side stage task: task=%d exists=%b", taskId,
+                task != null);
+        if (task == null) return false;
+        wct.reparent(task.token, newParent, false /* onTop */);
+        return true;
+    }
+
     private void sendStatusChanged() {
         mCallbacks.onStatusChanged(mRootTaskInfo.isVisible, mChildrenTaskInfo.size() > 0);
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
index 9b27e41..3d79a1c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
@@ -30,6 +30,7 @@
 import android.view.SurfaceControl;
 import android.window.TransitionInfo;
 
+import com.android.window.flags.Flags;
 import com.android.wm.shell.common.RemoteCallable;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SingleInstanceRemoteListener;
@@ -71,9 +72,17 @@
 
             final int mode = change.getMode();
             final boolean isBackGesture = change.hasFlags(FLAG_BACK_GESTURE_ANIMATED);
-            if (taskInfo.getActivityType() == ACTIVITY_TYPE_HOME
-                    && (TransitionUtil.isOpenOrCloseMode(mode) || isBackGesture)) {
-                notifyHomeVisibilityChanged(TransitionUtil.isOpeningType(mode) || isBackGesture);
+            if (taskInfo.getActivityType() == ACTIVITY_TYPE_HOME) {
+                if (Flags.migratePredictiveBackTransition()) {
+                    if (!isBackGesture && TransitionUtil.isOpenOrCloseMode(mode)) {
+                        notifyHomeVisibilityChanged(TransitionUtil.isOpeningType(mode));
+                    }
+                } else {
+                    if (TransitionUtil.isOpenOrCloseMode(mode) || isBackGesture) {
+                        notifyHomeVisibilityChanged(TransitionUtil.isOpeningType(mode)
+                                || isBackGesture);
+                    }
+                }
             }
         }
     }
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 81251b8..aa43c8d 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
@@ -114,6 +114,7 @@
     private final Choreographer mChoreographer;
     private final SyncTransactionQueue mSyncQueue;
     private final SplitScreenController mSplitScreenController;
+    private final WindowManagerWrapper mWindowManagerWrapper;
 
     private WindowDecorationViewHolder mWindowDecorViewHolder;
     private View.OnClickListener mOnCaptionButtonClickListener;
@@ -188,7 +189,9 @@
                 taskInfo, taskSurface, handler, bgExecutor, choreographer, syncQueue,
                 rootTaskDisplayAreaOrganizer, genericLinksParser, SurfaceControl.Builder::new,
                 SurfaceControl.Transaction::new,  WindowContainerTransaction::new,
-                SurfaceControl::new, new SurfaceControlViewHostFactory() {},
+                SurfaceControl::new, new WindowManagerWrapper(
+                        context.getSystemService(WindowManager.class)),
+                new SurfaceControlViewHostFactory() {},
                 DefaultMaximizeMenuFactory.INSTANCE, DefaultHandleMenuFactory.INSTANCE,
                 multiInstanceHelper);
     }
@@ -211,6 +214,7 @@
             Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
             Supplier<WindowContainerTransaction> windowContainerTransactionSupplier,
             Supplier<SurfaceControl> surfaceControlSupplier,
+            WindowManagerWrapper windowManagerWrapper,
             SurfaceControlViewHostFactory surfaceControlViewHostFactory,
             MaximizeMenuFactory maximizeMenuFactory,
             HandleMenuFactory handleMenuFactory,
@@ -229,6 +233,7 @@
         mMaximizeMenuFactory = maximizeMenuFactory;
         mHandleMenuFactory = handleMenuFactory;
         mMultiInstanceHelper = multiInstanceHelper;
+        mWindowManagerWrapper = windowManagerWrapper;
     }
 
     /**
@@ -574,7 +579,8 @@
             return new AppHandleViewHolder(
                     mResult.mRootView,
                     mOnCaptionTouchListener,
-                    mOnCaptionButtonClickListener
+                    mOnCaptionButtonClickListener,
+                    mWindowManagerWrapper
             );
         } else if (mRelayoutParams.mLayoutResId
                 == R.layout.desktop_mode_app_header) {
@@ -988,6 +994,7 @@
         updateGenericLink();
         mHandleMenu = mHandleMenuFactory.create(
                 this,
+                mWindowManagerWrapper,
                 mRelayoutParams.mLayoutResId,
                 mAppIconBitmap,
                 mAppName,
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 34de94e..748046e 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
@@ -64,6 +64,7 @@
  */
 class HandleMenu(
     private val parentDecor: DesktopModeWindowDecoration,
+    private val windowManagerWrapper: WindowManagerWrapper,
     private val layoutResId: Int,
     private val appIconBitmap: Bitmap?,
     private val appName: CharSequence?,
@@ -178,7 +179,7 @@
         handleMenuViewContainer =
             if (!taskInfo.isFreeform && Flags.enableAdditionalWindowsAboveStatusBar()) {
                 AdditionalSystemViewContainer(
-                    context = context,
+                    windowManagerWrapper = windowManagerWrapper,
                     taskId = taskInfo.taskId,
                     x = x,
                     y = y,
@@ -635,6 +636,7 @@
 interface HandleMenuFactory {
     fun create(
         parentDecor: DesktopModeWindowDecoration,
+        windowManagerWrapper: WindowManagerWrapper,
         layoutResId: Int,
         appIconBitmap: Bitmap?,
         appName: CharSequence?,
@@ -652,6 +654,7 @@
 object DefaultHandleMenuFactory : HandleMenuFactory {
     override fun create(
         parentDecor: DesktopModeWindowDecoration,
+        windowManagerWrapper: WindowManagerWrapper,
         layoutResId: Int,
         appIconBitmap: Bitmap?,
         appName: CharSequence?,
@@ -665,6 +668,7 @@
     ): HandleMenu {
         return HandleMenu(
             parentDecor,
+            windowManagerWrapper,
             layoutResId,
             appIconBitmap,
             appName,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowManagerWrapper.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowManagerWrapper.kt
new file mode 100644
index 0000000..5c2ff1b
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowManagerWrapper.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor
+
+import android.view.View
+import android.view.WindowManager
+
+/**
+ * A wrapper for [WindowManager] to make view manipulation operations related to window
+ * decors more testable.
+ */
+class WindowManagerWrapper (
+    private val windowManager: WindowManager
+){
+
+    fun addView(v: View, lp: WindowManager.LayoutParams) {
+        windowManager.addView(v, lp)
+    }
+
+    fun removeViewImmediate(v: View) {
+        windowManager.removeViewImmediate(v)
+    }
+
+    fun updateViewLayout(v: View, lp: WindowManager.LayoutParams) {
+        windowManager.updateViewLayout(v, lp)
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
index cadd80e..226b0fb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
@@ -24,13 +24,14 @@
 import android.view.SurfaceControl
 import android.view.View
 import android.view.WindowManager
+import com.android.wm.shell.windowdecor.WindowManagerWrapper
 
 /**
  * An [AdditionalViewContainer] that uses the system [WindowManager] instance. Intended
  * for view containers that should be above the status bar layer.
  */
 class AdditionalSystemViewContainer(
-    context: Context,
+    private val windowManagerWrapper: WindowManagerWrapper,
     taskId: Int,
     x: Int,
     y: Int,
@@ -39,9 +40,20 @@
     flags: Int,
     override val view: View
 ) : AdditionalViewContainer() {
+    val lp: WindowManager.LayoutParams = WindowManager.LayoutParams(
+        width, height, x, y,
+        WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL,
+        flags,
+        PixelFormat.TRANSPARENT
+    ).apply {
+        title = "Additional view container of Task=$taskId"
+        gravity = Gravity.LEFT or Gravity.TOP
+        setTrustedOverlay()
+    }
 
     constructor(
         context: Context,
+        windowManagerWrapper: WindowManagerWrapper,
         taskId: Int,
         x: Int,
         y: Int,
@@ -50,7 +62,7 @@
         flags: Int,
         @LayoutRes layoutId: Int
     ) : this(
-        context = context,
+        windowManagerWrapper = windowManagerWrapper,
         taskId = taskId,
         x = x,
         y = y,
@@ -61,9 +73,16 @@
     )
 
     constructor(
-        context: Context, taskId: Int, x: Int, y: Int, width: Int, height: Int, flags: Int
+        context: Context,
+        windowManagerWrapper: WindowManagerWrapper,
+        taskId: Int,
+        x: Int,
+        y: Int,
+        width: Int,
+        height: Int,
+        flags: Int
     ) : this(
-        context = context,
+        windowManagerWrapper = windowManagerWrapper,
         taskId = taskId,
         x = x,
         y = y,
@@ -73,24 +92,12 @@
         view = View(context)
     )
 
-    val windowManager: WindowManager? = context.getSystemService(WindowManager::class.java)
-
     init {
-        val lp = WindowManager.LayoutParams(
-            width, height, x, y,
-            WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL,
-            flags,
-            PixelFormat.TRANSPARENT
-        ).apply {
-            title = "Additional view container of Task=$taskId"
-            gravity = Gravity.LEFT or Gravity.TOP
-            setTrustedOverlay()
-        }
-        windowManager?.addView(view, lp)
+        windowManagerWrapper.addView(view, lp)
     }
 
     override fun releaseView() {
-        windowManager?.removeViewImmediate(view)
+        windowManagerWrapper.removeViewImmediate(view)
     }
 
     override fun setPosition(t: SurfaceControl.Transaction, x: Float, y: Float) {
@@ -98,6 +105,6 @@
             this.x = x.toInt()
             this.y = y.toInt()
         }
-        windowManager?.updateViewLayout(view, lp)
+        windowManagerWrapper.updateViewLayout(view, lp)
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
index 510032b..dfa5ab4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
@@ -32,6 +32,7 @@
 import com.android.window.flags.Flags
 import com.android.wm.shell.R
 import com.android.wm.shell.shared.animation.Interpolators
+import com.android.wm.shell.windowdecor.WindowManagerWrapper
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
 
 /**
@@ -41,14 +42,14 @@
 internal class AppHandleViewHolder(
     rootView: View,
     onCaptionTouchListener: View.OnTouchListener,
-    onCaptionButtonClickListener: OnClickListener
+    onCaptionButtonClickListener: OnClickListener,
+    private val windowManagerWrapper: WindowManagerWrapper
 ) : WindowDecorationViewHolder(rootView) {
 
     companion object {
         private const val CAPTION_HANDLE_ANIMATION_DURATION: Long = 100
     }
     private lateinit var taskInfo: RunningTaskInfo
-    private val windowManager = context.getSystemService(WindowManager::class.java)
     private val captionView: View = rootView.requireViewById(R.id.desktop_mode_caption)
     private val captionHandle: ImageButton = rootView.requireViewById(R.id.caption_handle)
     private val inputManager = context.getSystemService(InputManager::class.java)
@@ -96,11 +97,12 @@
                                           handleWidth: Int,
                                           handleHeight: Int) {
         if (!Flags.enableAdditionalWindowsAboveStatusBar()) return
-        statusBarInputLayer = AdditionalSystemViewContainer(context, taskInfo.taskId,
-            handlePosition.x, handlePosition.y, handleWidth, handleHeight,
+        statusBarInputLayer = AdditionalSystemViewContainer(context, windowManagerWrapper,
+            taskInfo.taskId, handlePosition.x, handlePosition.y, handleWidth, handleHeight,
             WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
-        val view = statusBarInputLayer?.view
-        val lp = view?.layoutParams as WindowManager.LayoutParams
+        val view = statusBarInputLayer?.view ?: error("Unable to find statusBarInputLayer View")
+        val lp = statusBarInputLayer?.lp ?: error("Unable to find statusBarInputLayer" +
+                "LayoutParams")
         lp.title = "Handle Input Layer of task " + taskInfo.taskId
         lp.setTrustedOverlay()
         // Make this window a spy window to enable it to pilfer pointers from the system-wide
@@ -120,7 +122,7 @@
             captionHandle.dispatchTouchEvent(event)
             true
         }
-        windowManager.updateViewLayout(view, lp)
+        windowManagerWrapper.updateViewLayout(view, lp)
     }
 
     private fun updateStatusBarInputLayer(globalPosition: Point) {
diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp
index 4d761e1..006a4a9 100644
--- a/libs/WindowManager/Shell/tests/unittest/Android.bp
+++ b/libs/WindowManager/Shell/tests/unittest/Android.bp
@@ -94,3 +94,10 @@
         "com.android.wm.shell.tests",
     ],
 }
+
+test_module_config {
+    name: "WMShellUnitTests_shell_back",
+    base: "WMShellUnitTests",
+    test_suites: ["device-tests"],
+    include_filters: ["com.android.wm.shell.back"],
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index a8d40db..386253c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -46,6 +46,7 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
+import android.app.KeyguardManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -136,6 +137,8 @@
 
         mMainExecutor = new TestShellExecutor();
         when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class));
+        when(mContext.getSystemService(KeyguardManager.class))
+                .thenReturn(mock(KeyguardManager.class));
         mShellInit = spy(new ShellInit(mMainExecutor));
         mShellController = spy(new ShellController(mContext, mShellInit, mShellCommandHandler,
                 mDisplayInsetsController, mMainExecutor));
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SideStageTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SideStageTests.java
deleted file mode 100644
index 549bd3f..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SideStageTests.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.splitscreen;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.verify;
-
-import android.app.ActivityManager;
-import android.view.SurfaceControl;
-import android.view.SurfaceSession;
-import android.window.WindowContainerTransaction;
-
-import androidx.test.annotation.UiThreadTest;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.launcher3.icons.IconProvider;
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.TestRunningTaskInfoBuilder;
-import com.android.wm.shell.common.SyncTransactionQueue;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
-
-import java.util.Optional;
-
-/** Tests for {@link SideStage} */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class SideStageTests extends ShellTestCase {
-    @Mock private ShellTaskOrganizer mTaskOrganizer;
-    @Mock private StageTaskListener.StageListenerCallbacks mCallbacks;
-    @Mock private SyncTransactionQueue mSyncQueue;
-    @Mock private ActivityManager.RunningTaskInfo mRootTask;
-    @Mock private SurfaceControl mRootLeash;
-    @Mock private IconProvider mIconProvider;
-    @Spy private WindowContainerTransaction mWct;
-    private SurfaceSession mSurfaceSession = new SurfaceSession();
-    private SideStage mSideStage;
-
-    @Before
-    @UiThreadTest
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mRootTask = new TestRunningTaskInfoBuilder().build();
-        mSideStage = new SideStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mCallbacks,
-                mSyncQueue, mSurfaceSession, mIconProvider, Optional.empty());
-        mSideStage.onTaskAppeared(mRootTask, mRootLeash);
-    }
-
-    @Test
-    public void testAddTask() {
-        final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
-
-        mSideStage.addTask(task, mWct);
-
-        verify(mWct).reparent(eq(task.token), eq(mRootTask.token), eq(true));
-    }
-
-    @Test
-    public void testRemoveTask() {
-        final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
-        assertThat(mSideStage.removeTask(task.taskId, null, mWct)).isFalse();
-
-        mSideStage.mChildrenTaskInfo.put(task.taskId, task);
-        assertThat(mSideStage.removeTask(task.taskId, null, mWct)).isTrue();
-        verify(mWct).reparent(eq(task.token), isNull(), eq(false));
-    }
-}
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 aa96c45..4de2278 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
@@ -74,7 +74,7 @@
         final SurfaceControl mRootLeash;
 
         TestStageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
-                ShellTaskOrganizer taskOrganizer, MainStage mainStage, SideStage sideStage,
+                ShellTaskOrganizer taskOrganizer, MainStage mainStage, StageTaskListener sideStage,
                 DisplayController displayController, DisplayImeController imeController,
                 DisplayInsetsController insetsController, SplitLayout splitLayout,
                 Transitions transitions, TransactionPool transactionPool,
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 abe3dcc..e167433 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
@@ -117,7 +117,7 @@
     private final TestShellExecutor mTestShellExecutor = new TestShellExecutor();
     private SplitLayout mSplitLayout;
     private MainStage mMainStage;
-    private SideStage mSideStage;
+    private StageTaskListener mSideStage;
     private StageCoordinator mStageCoordinator;
     private SplitScreenTransitions mSplitScreenTransitions;
 
@@ -137,7 +137,7 @@
                 StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mSurfaceSession,
                 mIconProvider, Optional.of(mWindowDecorViewModel)));
         mMainStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
-        mSideStage = spy(new SideStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
+        mSideStage = spy(new StageTaskListener(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
                 StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mSurfaceSession,
                 mIconProvider, Optional.of(mWindowDecorViewModel)));
         mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
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 0054cb6..c9e1414 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
@@ -99,7 +99,7 @@
     @Mock
     private MainStage mMainStage;
     @Mock
-    private SideStage mSideStage;
+    private StageTaskListener mSideStage;
     @Mock
     private SplitLayout mSplitLayout;
     @Mock
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 946a7ef..acd612e 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
@@ -25,6 +25,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeFalse;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -52,6 +53,7 @@
 import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
 
 import java.util.Optional;
 
@@ -76,6 +78,8 @@
     private IconProvider mIconProvider;
     @Mock
     private WindowDecorViewModel mWindowDecorViewModel;
+    @Spy
+    private WindowContainerTransaction mWct;
     @Captor
     private ArgumentCaptor<SyncTransactionQueue.TransactionRunnable> mRunnableCaptor;
     private SurfaceSession mSurfaceSession = new SurfaceSession();
@@ -177,4 +181,22 @@
         mStageTaskListener.evictAllChildren(wct);
         assertFalse(wct.isEmpty());
     }
+
+    @Test
+    public void testAddTask() {
+        final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
+        mStageTaskListener.addTask(task, mWct);
+
+        verify(mWct).reparent(eq(task.token), eq(mRootTask.token), eq(true));
+    }
+
+    @Test
+    public void testRemoveTask() {
+        final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
+        assertThat(mStageTaskListener.removeTask(task.taskId, null, mWct)).isFalse();
+
+        mStageTaskListener.mChildrenTaskInfo.put(task.taskId, task);
+        assertThat(mStageTaskListener.removeTask(task.taskId, null, mWct)).isTrue();
+        verify(mWct).reparent(eq(task.token), isNull(), eq(false));
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java
index d2adae1..f51a960 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java
@@ -38,6 +38,9 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.view.SurfaceControl;
 import android.window.TransitionInfo;
 import android.window.TransitionInfo.TransitionMode;
@@ -46,6 +49,7 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
+import com.android.window.flags.Flags;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestShellExecutor;
@@ -57,6 +61,7 @@
 import com.android.wm.shell.sysui.ShellInit;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -70,6 +75,8 @@
 @RunWith(AndroidJUnit4.class)
 public class HomeTransitionObserverTest extends ShellTestCase {
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
     private final ShellTaskOrganizer mOrganizer = mock(ShellTaskOrganizer.class);
     private final TransactionPool mTransactionPool = mock(TransactionPool.class);
     private final Context mContext =
@@ -187,6 +194,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_MIGRATE_PREDICTIVE_BACK_TRANSITION)
     public void testHomeActivityWithBackGestureNotifiesHomeIsVisible() throws RemoteException {
         TransitionInfo info = mock(TransitionInfo.class);
         TransitionInfo.Change change = mock(TransitionInfo.Change.class);
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 596adfb..258c860 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
@@ -173,9 +173,12 @@
     @Mock
     private AppToWebGenericLinksParser mMockGenericLinksParser;
     @Mock
+    private WindowManager mMockWindowManager;
+    @Mock
     private HandleMenu mMockHandleMenu;
     @Mock
     private HandleMenuFactory mMockHandleMenuFactory;
+    @Mock
     private MultiInstanceHelper mMockMultiInstanceHelper;
     @Captor
     private ArgumentCaptor<Function1<Boolean, Unit>> mOnMaxMenuHoverChangeListener;
@@ -220,9 +223,10 @@
         final Display defaultDisplay = mock(Display.class);
         doReturn(defaultDisplay).when(mMockDisplayController).getDisplay(Display.DEFAULT_DISPLAY);
         doReturn(mInsetsState).when(mMockDisplayController).getInsetsState(anyInt());
-        when(mMockHandleMenuFactory.create(any(), anyInt(), any(), any(),
+        when(mMockHandleMenuFactory.create(any(), any(), anyInt(), any(), any(),
                 any(), anyBoolean(), anyBoolean(), any(), anyInt(), anyInt(), anyInt()))
                 .thenReturn(mMockHandleMenu);
+        when(mMockMultiInstanceHelper.supportsMultiInstanceSplit(any())).thenReturn(false);
     }
 
     @After
@@ -385,6 +389,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
     public void updateRelayoutParams_fullscreen_inputChannelNotNeeded() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
         taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
@@ -401,6 +406,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
     public void updateRelayoutParams_multiwindow_inputChannelNotNeeded() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
         taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
@@ -491,7 +497,7 @@
                 .isTrue();
     }
 
-    @DisableFlags(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
+    @Test
     public void relayout_fullscreenTask_appliesTransactionImmediately() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
         final DesktopModeWindowDecoration spyWindowDecor = spy(createWindowDecoration(taskInfo));
@@ -518,7 +524,6 @@
     }
 
     @Test
-    @DisableFlags(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
     public void relayout_fullscreenTask_doesNotCreateViewHostImmediately() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
         final DesktopModeWindowDecoration spyWindowDecor = spy(createWindowDecoration(taskInfo));
@@ -530,7 +535,6 @@
     }
 
     @Test
-    @DisableFlags(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
     public void relayout_fullscreenTask_postsViewHostCreation() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
         final DesktopModeWindowDecoration spyWindowDecor = spy(createWindowDecoration(taskInfo));
@@ -559,7 +563,6 @@
     }
 
     @Test
-    @DisableFlags(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
     public void relayout_removesExistingHandlerCallback() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
         final DesktopModeWindowDecoration spyWindowDecor = spy(createWindowDecoration(taskInfo));
@@ -574,7 +577,6 @@
     }
 
     @Test
-    @DisableFlags(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
     public void close_removesExistingHandlerCallback() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
         final DesktopModeWindowDecoration spyWindowDecor = spy(createWindowDecoration(taskInfo));
@@ -826,7 +828,7 @@
     }
 
     private void verifyHandleMenuCreated(@Nullable Uri uri) {
-        verify(mMockHandleMenuFactory).create(any(), anyInt(), any(), any(),
+        verify(mMockHandleMenuFactory).create(any(), any(), anyInt(), any(), any(),
                 any(), anyBoolean(), anyBoolean(), eq(uri), anyInt(), anyInt(), anyInt());
     }
 
@@ -894,8 +896,9 @@
                 mMockChoreographer, mMockSyncQueue, mMockRootTaskDisplayAreaOrganizer,
                 mMockGenericLinksParser, SurfaceControl.Builder::new, mMockTransactionSupplier,
                 WindowContainerTransaction::new, SurfaceControl::new,
+                new WindowManagerWrapper(mMockWindowManager),
                 mMockSurfaceControlViewHostFactory, maximizeMenuFactory, mMockHandleMenuFactory,
-                        mMockMultiInstanceHelper);
+                mMockMultiInstanceHelper);
         windowDecor.setCaptionListeners(mMockTouchEventListener, mMockTouchEventListener,
                 mMockTouchEventListener, mMockTouchEventListener);
         windowDecor.setExclusionRegionListener(mMockExclusionRegionListener);
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 627dfe7..100abbb 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
@@ -33,6 +33,7 @@
 import android.view.SurfaceControl
 import android.view.SurfaceControlViewHost
 import android.view.View
+import android.view.WindowManager
 import androidx.core.graphics.toPointF
 import androidx.test.filters.SmallTest
 import com.android.window.flags.Flags
@@ -77,6 +78,8 @@
     @Mock
     private lateinit var mockDesktopWindowDecoration: DesktopModeWindowDecoration
     @Mock
+    private lateinit var mockWindowManager: WindowManager
+    @Mock
     private lateinit var onClickListener: View.OnClickListener
     @Mock
     private lateinit var onTouchListener: View.OnTouchListener
@@ -230,8 +233,9 @@
             }
             else -> error("Invalid windowing mode")
         }
-        val handleMenu = HandleMenu(mockDesktopWindowDecoration, layoutId, appIcon, appName,
-            splitScreenController, shouldShowWindowingPill = true,
+        val handleMenu = HandleMenu(mockDesktopWindowDecoration,
+            WindowManagerWrapper(mockWindowManager),
+            layoutId, appIcon, appName, splitScreenController, shouldShowWindowingPill = true,
             shouldShowNewWindowButton = true,
             null /* openInBrowserLink */, captionWidth = HANDLE_WIDTH, captionHeight = 50,
             captionX = captionX
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainerTest.kt
index 28b4eb6..0f52ed7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainerTest.kt
@@ -25,6 +25,7 @@
 import androidx.test.filters.SmallTest
 import com.android.wm.shell.R
 import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.windowdecor.WindowManagerWrapper
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -70,6 +71,7 @@
                 WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
         viewContainer = AdditionalSystemViewContainer(
             mockContext,
+            WindowManagerWrapper(mockWindowManager),
             TASK_ID,
             X,
             Y,
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 1930c3d..b84990b 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -288,8 +288,7 @@
 
     /**
      * Returns a proxy MediaRouter2 instance that allows you to control the routing of an app
-     * specified by {@code clientPackageName}. Returns {@code null} if the specified package name
-     * does not exist.
+     * specified by {@code clientPackageName}.
      *
      * <p>Proxy MediaRouter2 instances operate differently than regular MediaRouter2 instances:
      *
diff --git a/media/tests/AudioPolicyTest/Android.bp b/media/tests/AudioPolicyTest/Android.bp
index 3dc2a0a..43b1a35 100644
--- a/media/tests/AudioPolicyTest/Android.bp
+++ b/media/tests/AudioPolicyTest/Android.bp
@@ -24,3 +24,11 @@
     resource_dirs: ["res"],
     test_suites: ["device-tests"],
 }
+
+test_module_config {
+    name: "audiopolicytest_audiopolicytest_audiopolicydeathtest_Presubmit",
+    base: "audiopolicytest",
+    test_suites: ["device-tests"],
+    include_filters: ["com.android.audiopolicytest.AudioPolicyDeathTest"],
+    include_annotations: ["android.platform.test.annotations.Presubmit"],
+}
diff --git a/packages/SettingsLib/aconfig/settingslib.aconfig b/packages/SettingsLib/aconfig/settingslib.aconfig
index 2b3862f..34b597b 100644
--- a/packages/SettingsLib/aconfig/settingslib.aconfig
+++ b/packages/SettingsLib/aconfig/settingslib.aconfig
@@ -129,3 +129,13 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "member_device_lea_active_state_sync_fix"
+    namespace: "cross_device_experiences"
+    description: "Gates whether to enable fix for member device active state sync on lea profile"
+    bug: "364201289"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index f739410..a0724b0 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -130,7 +130,7 @@
     <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"સંપર્કો અને કૉલ ઇતિહાસ ઍક્સેસ કરવા દો"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"માહિતીનો ઉપયોગ કૉલની ઘોષણાઓ અને વધુ બાબતો માટે કરવામાં આવશે"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ઇન્ટરનેટ કનેક્શન શેરિંગ"</string>
-    <string name="bluetooth_profile_map" msgid="8907204701162107271">"ટેક્સ્ટ સંદેશા"</string>
+    <string name="bluetooth_profile_map" msgid="8907204701162107271">"ટેક્સ્ટ મેસેજ"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"સિમ ઍક્સેસ"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ઑડિયો: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ઑડિયો"</string>
diff --git a/packages/SettingsLib/res/values/config.xml b/packages/SettingsLib/res/values/config.xml
index 68b81db..3c3de04 100644
--- a/packages/SettingsLib/res/values/config.xml
+++ b/packages/SettingsLib/res/values/config.xml
@@ -31,4 +31,14 @@
     <!-- Control whether status bar should distinguish HSPA data icon form UMTS
     data icon on devices -->
     <bool name="config_hspa_data_distinguishable">false</bool>
+
+    <!-- Edit User avatar explicit package name -->
+    <string name="config_avatar_picker_package" translatable="false">
+        com.android.avatarpicker
+    </string>
+
+    <!-- Edit User avatar explicit activity class -->
+    <string name="config_avatar_picker_class" translatable="false">
+        com.android.avatarpicker.ui.AvatarPickerActivity
+    </string>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java b/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java
index cdc3f12..f38e91a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java
@@ -32,6 +32,7 @@
 
 import com.android.internal.util.UserIcons;
 import com.android.settingslib.drawable.CircleFramedDrawable;
+import com.android.settingslib.R;
 import com.android.settingslib.utils.ThreadUtils;
 
 import com.google.common.util.concurrent.FutureCallback;
@@ -132,6 +133,13 @@
         intent.addCategory(Intent.CATEGORY_DEFAULT);
         if (Flags.avatarSync()) {
             intent.putExtra(EXTRA_IS_USER_NEW, isUserNew);
+            // Fix vulnerability b/341688848 by explicitly set the class name of avatar picker.
+            if (Flags.fixAvatarCrossUserLeak()) {
+                final String packageName =
+                        mActivity.getString(R.string.config_avatar_picker_package);
+                final String className = mActivity.getString(R.string.config_avatar_picker_class);
+                intent.setClassName(packageName, className);
+            }
         } else {
             // SettingsLib is used by multiple apps therefore we need to know out of all apps
             // using settingsLib which one is the one we return value to.
diff --git a/packages/SettingsLib/tests/integ/Android.bp b/packages/SettingsLib/tests/integ/Android.bp
index 33d23a3..48a1af6 100644
--- a/packages/SettingsLib/tests/integ/Android.bp
+++ b/packages/SettingsLib/tests/integ/Android.bp
@@ -72,3 +72,10 @@
     dxflags: ["--multi-dex"],
     manifest: "AndroidManifest.xml",
 }
+
+test_module_config {
+    name: "SettingsLibTests_settingslib_users",
+    base: "SettingsLibTests",
+    test_suites: ["device-tests"],
+    include_filters: ["com.android.settingslib.users."],
+}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index ec50323..e85ba45 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2173,8 +2173,7 @@
                                             (1 << AudioManager.STREAM_NOTIFICATION) |
                                             (1 << AudioManager.STREAM_SYSTEM) |
                                             (1 << AudioManager.STREAM_SYSTEM_ENFORCED);
-            if (!mContext.getResources().getBoolean(
-                    com.android.internal.R.bool.config_voice_capable)) {
+            if (!getTelephonyManager().isVoiceCapable()) {
                 ringerModeAffectedStreams |= (1 << AudioManager.STREAM_MUSIC);
             }
             loadSetting(stmt, Settings.System.MODE_RINGER_STREAMS_AFFECTED,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index 121bd3e..bfbf41d 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -99,6 +99,12 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.print("SyncDisabledForTests: ");
+        MyShellCommand.getSyncDisabledForTests(pw, pw);
+
+        pw.print("Is mainline: ");
+        pw.println(UpdatableDeviceConfigServiceReadiness.shouldStartUpdatableService());
+
         final IContentProvider iprovider = mProvider.getIContentProvider();
         pw.println("DeviceConfig flags:");
         for (String line : MyShellCommand.listAll(iprovider)) {
@@ -232,6 +238,17 @@
             return Binder.getCallingUid() == Process.ROOT_UID;
         }
 
+        private static int getSyncDisabledForTests(PrintWriter pOut, PrintWriter pErr) {
+            int syncDisabledModeInt = DeviceConfig.getSyncDisabledMode();
+            String syncDisabledModeString = formatSyncDisabledMode(syncDisabledModeInt);
+            if (syncDisabledModeString == null) {
+                pErr.println("Unknown mode: " + syncDisabledModeInt);
+                return -1;
+            }
+            pOut.println(syncDisabledModeString);
+            return 0;
+        }
+
       public static HashMap<String, String> getAllFlags(IContentProvider provider) {
         HashMap<String, String> allFlags = new HashMap<String, String>();
         for (DeviceConfig.Properties properties : DeviceConfig.getAllProperties()) {
@@ -597,14 +614,7 @@
                     DeviceConfig.setSyncDisabledMode(syncDisabledModeArg);
                     break;
                 case GET_SYNC_DISABLED_FOR_TESTS:
-                    int syncDisabledModeInt = DeviceConfig.getSyncDisabledMode();
-                    String syncDisabledModeString = formatSyncDisabledMode(syncDisabledModeInt);
-                    if (syncDisabledModeString == null) {
-                        perr.println("Unknown mode: " + syncDisabledModeInt);
-                        return -1;
-                    }
-                    pout.println(syncDisabledModeString);
-                    break;
+                    return getSyncDisabledForTests(pout, perr);
                 default:
                     perr.println("Unspecified command");
                     return -1;
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/Android.bp
index c60eb61..fb1f715 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/Android.bp
+++ b/packages/SystemUI/accessibility/accessibilitymenu/Android.bp
@@ -41,6 +41,7 @@
         "SettingsLibDisplayUtils",
         "SettingsLibSettingsTheme",
         "com_android_a11y_menu_flags_lib",
+        "//frameworks/libs/systemui:view_capture",
     ],
 
     optimize: {
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/layout/grid_item.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/layout/grid_item.xml
index fd9a9c6..3c73eca 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/layout/grid_item.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/layout/grid_item.xml
@@ -3,8 +3,7 @@
     android:id="@+id/shortcutItem"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:paddingTop="@dimen/grid_item_padding"
-    android:paddingBottom="@dimen/grid_item_padding"
+    android:padding="@dimen/grid_item_padding"
     android:gravity="center">
 
   <ImageButton
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/layout/paged_menu.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/layout/paged_menu.xml
index 6be7655..adaa655 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/layout/paged_menu.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/layout/paged_menu.xml
@@ -1,25 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
-<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="@dimen/row_width"
     android:layout_height="match_parent"
-    android:id="@+id/coordinatorLayout"
-    android:background="@drawable/view_background"
-    >
-  <LinearLayout
+    android:orientation="vertical"
+    android:background="@drawable/view_background">
+
+  <androidx.viewpager2.widget.ViewPager2
+      android:id="@+id/view_pager"
       android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:orientation="vertical">
+      android:layout_height="0dp"
+      android:layout_weight="1"
+      android:paddingTop="@dimen/table_margin_top"
+      android:paddingBottom="@dimen/a11ymenu_layout_margin"
+      android:gravity="center"
+      />
 
-    <androidx.viewpager2.widget.ViewPager2
-        android:id="@+id/view_pager"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingTop="@dimen/table_margin_top"
-        android:paddingBottom="@dimen/a11ymenu_layout_margin"
-        android:layout_gravity="center"
-        android:gravity="center"
-        />
-
-    <include layout="@layout/footerlayout_switch_page"/>
-  </LinearLayout>
-</androidx.coordinatorlayout.widget.CoordinatorLayout>
+  <include layout="@layout/footerlayout_switch_page"/>
+</LinearLayout>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuFooter.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuFooter.java
index 78fbf01..136a4ed 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuFooter.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuFooter.java
@@ -55,6 +55,8 @@
     private View mBottomListDivider;
     private final A11yMenuFooterCallBack mCallBack;
     private final ViewGroup mMenuLayout;
+    private ViewGroup mFooterContainer;
+    private int mFooterContainerBaseHeight = 0;
     private int mRightToLeftDirection = LAYOUT_DIRECTION_LTR;
 
     public A11yMenuFooter(ViewGroup menuLayout, A11yMenuFooterCallBack callBack) {
@@ -74,6 +76,15 @@
                 ? mPageRightBtn : mPageLeftBtn;
     }
 
+    void adjustFooterToDensityScale(float densityScale) {
+        mFooterContainer.getLayoutParams().height =
+                (int) (mFooterContainerBaseHeight / densityScale);
+    }
+
+    int getHeight() {
+        return mFooterContainer.getLayoutParams().height;
+    }
+
     /** Sets right to left direction of footer. */
     public void updateRightToLeftDirection(Configuration configuration) {
         mRightToLeftDirection = TextUtils.getLayoutDirectionFromLocale(
@@ -85,8 +96,9 @@
     }
 
     private void configureFooterLayout(ViewGroup menuLayout) {
-        ViewGroup footerContainer = menuLayout.findViewById(R.id.footerlayout);
-        footerContainer.setVisibility(View.VISIBLE);
+        mFooterContainer = menuLayout.findViewById(R.id.footerlayout);
+        mFooterContainer.setVisibility(View.VISIBLE);
+        mFooterContainerBaseHeight = mFooterContainer.getLayoutParams().height;
 
         mPageLeftBtn = menuLayout.findViewById(R.id.menu_left_button);
         mPageRightBtn = menuLayout.findViewById(R.id.menu_right_button);
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
index 448472d..3db61a5 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
@@ -22,6 +22,8 @@
 import static android.view.View.ACCESSIBILITY_LIVE_REGION_POLITE;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
 
+import static com.android.app.viewcapture.ViewCaptureFactory.getViewCaptureAwareWindowManagerInstance;
+
 import static java.lang.Math.max;
 
 import android.animation.Animator;
@@ -53,6 +55,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.UiContext;
 
+import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
 import com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService;
 import com.android.systemui.accessibility.accessibilitymenu.Flags;
 import com.android.systemui.accessibility.accessibilitymenu.R;
@@ -143,7 +146,9 @@
         final Display display = mDisplayManager.getDisplay(DEFAULT_DISPLAY);
         final Context uiContext = mService.createWindowContext(
                 display, TYPE_ACCESSIBILITY_OVERLAY, /* options= */null);
-        final WindowManager windowManager = uiContext.getSystemService(WindowManager.class);
+        final ViewCaptureAwareWindowManager windowManager =
+                getViewCaptureAwareWindowManagerInstance(uiContext,
+                        com.android.systemui.Flags.enableViewCaptureTracing());
         mLayout = new A11yMenuFrameLayout(uiContext);
         updateLayoutPosition(uiContext);
         inflateLayoutAndSetOnTouchListener(mLayout, uiContext);
@@ -158,8 +163,8 @@
 
     public void clearLayout() {
         if (mLayout != null) {
-            WindowManager windowManager =
-                    mLayout.getContext().getSystemService(WindowManager.class);
+            ViewCaptureAwareWindowManager windowManager = getViewCaptureAwareWindowManagerInstance(
+                    mLayout.getContext(), com.android.systemui.Flags.enableViewCaptureTracing());
             if (windowManager != null) {
                 windowManager.removeView(mLayout);
             }
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuViewPager.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuViewPager.java
index a29ce82..35f1248 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuViewPager.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuViewPager.java
@@ -28,6 +28,7 @@
 import android.view.WindowMetrics;
 import android.widget.GridView;
 
+import androidx.recyclerview.widget.RecyclerView;
 import androidx.viewpager2.widget.ViewPager2;
 
 import com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService;
@@ -163,7 +164,9 @@
         mA11yMenuShortcutList = shortcutDataList;
         initViewPager();
         initChildPage();
-        mA11yMenuFooter = new A11yMenuFooter(a11yMenuLayout, mFooterCallbacks);
+        if (mA11yMenuFooter == null) {
+            mA11yMenuFooter = new A11yMenuFooter(a11yMenuLayout, mFooterCallbacks);
+        }
         mA11yMenuFooter.updateRightToLeftDirection(
                 a11yMenuLayout.getResources().getConfiguration());
         updateFooterState();
@@ -233,11 +236,17 @@
                                     return;
                                 }
 
-                                if (mGridPageList.isEmpty()) {
+                                if (mViewPagerAdapter.getItemCount() == 0) {
                                     return;
                                 }
 
-                                GridView firstGridView = mGridPageList.get(0);
+                                RecyclerView.ViewHolder viewHolder =
+                                        ((RecyclerView) mViewPager.getChildAt(0))
+                                                .findViewHolderForAdapterPosition(0);
+                                if (viewHolder == null) {
+                                    return;
+                                }
+                                GridView firstGridView = (GridView) viewHolder.itemView;
                                 if (firstGridView == null
                                         || firstGridView.getChildAt(0) == null) {
                                     return;
@@ -280,10 +289,8 @@
             DisplayMetrics displayMetrics = mService.getResources().getDisplayMetrics();
             float densityScale = (float) displayMetrics.densityDpi
                     / DisplayMetrics.DENSITY_DEVICE_STABLE;
-            View footerLayout = mA11yMenuLayout.findViewById(R.id.footerlayout);
             // Keeps footer window height unchanged no matter the density is changed.
-            footerLayout.getLayoutParams().height =
-                    (int) (footerLayout.getLayoutParams().height / densityScale);
+            mA11yMenuFooter.adjustFooterToDensityScale(densityScale);
             // Adjust the view pager height for system bar and display cutout insets.
             WindowManager windowManager = mA11yMenuLayout.getContext()
                     .getSystemService(WindowManager.class);
@@ -292,20 +299,18 @@
                     WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout());
             viewPagerHeight =
                     windowMetric.getBounds().height()
-                            - footerLayout.getLayoutParams().height
+                            - mA11yMenuFooter.getHeight()
                             - windowInsets.bottom;
             // Sets vertical interval between grid items.
             int interval =
                     (viewPagerHeight - topMargin - defaultMargin
                             - (rowsInGridView * gridItemHeight))
                             / (rowsInGridView + 1);
-            for (GridView gridView : mGridPageList) {
-                gridView.setVerticalSpacing(interval);
-            }
+            mViewPagerAdapter.setVerticalSpacing(interval);
 
             // Sets padding to view pager.
             final int finalMarginTop = interval + topMargin;
-            mViewPager.setPadding(defaultMargin, finalMarginTop, defaultMargin, defaultMargin);
+            mViewPager.setPadding(0, finalMarginTop, 0, defaultMargin);
         }
         final ViewGroup.LayoutParams layoutParams = mViewPager.getLayoutParams();
         layoutParams.height = viewPagerHeight;
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/ViewPagerAdapter.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/ViewPagerAdapter.java
index 152ff68..4b14e51 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/ViewPagerAdapter.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/ViewPagerAdapter.java
@@ -36,11 +36,19 @@
     /** List of shortcuts, split into sub lists per page */
     private List<List<A11yMenuShortcut>> mShortcutList;
     private final AccessibilityMenuService mService;
+    private int mVerticalSpacing = 0;
 
     ViewPagerAdapter(AccessibilityMenuService service) {
         mService = service;
     }
 
+    public void setVerticalSpacing(int spacing) {
+        if (mVerticalSpacing != spacing) {
+            mVerticalSpacing = spacing;
+            notifyDataSetChanged();
+        }
+    }
+
     public void set(List<List<A11yMenuShortcut>> tList) {
         mShortcutList = tList;
         notifyDataSetChanged();
@@ -61,6 +69,7 @@
         GridView gridView = (GridView) holder.itemView;
         gridView.setNumColumns(A11yMenuViewPager.GridViewParams.getGridColumnCount(mService));
         gridView.setAdapter(adapter);
+        gridView.setVerticalSpacing(mVerticalSpacing);
     }
 
     @Override
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index cf13621..be748da 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -637,10 +637,13 @@
 }
 
 flag {
-   name: "smartspace_remoteviews_rendering"
+   name: "smartspace_remoteviews_rendering_fix"
    namespace: "systemui"
    description: "Indicate Smartspace RemoteViews rendering"
    bug: "326292691"
+   metadata {
+     purpose: PURPOSE_BUGFIX
+   }
 }
 
 flag {
@@ -651,6 +654,13 @@
 }
 
 flag {
+    name: "smartspace_viewpager2"
+    namespace: "systemui"
+    description: "Use viewpager2 in Smartspace"
+    bug: "259566300"
+}
+
+flag {
    name: "pin_input_field_styled_focus_state"
    namespace: "systemui"
    description: "Enables styled focus states on pin input field if keyboard is connected"
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt
index 9f78d69..34eafde 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt
@@ -102,6 +102,7 @@
 import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel
 import com.android.systemui.common.shared.model.Text.Companion.loadText
 import com.android.systemui.common.ui.compose.Icon
+import com.android.systemui.compose.modifiers.sysuiResTag
 import com.android.systemui.fold.ui.composable.foldPosture
 import com.android.systemui.fold.ui.helper.FoldPosture
 import com.android.systemui.res.R
@@ -259,8 +260,11 @@
                         viewModel = viewModel.message,
                         modifier = Modifier.align(Alignment.TopCenter),
                     )
-
-                    OutputArea(viewModel = viewModel, modifier = Modifier.align(Alignment.Center))
+                    OutputArea(
+                        viewModel = viewModel,
+                        modifier =
+                            Modifier.align(Alignment.Center).sysuiResTag("bouncer_text_entry")
+                    )
 
                     ActionArea(
                         viewModel = viewModel,
@@ -310,8 +314,11 @@
                         StatusMessage(
                             viewModel = viewModel.message,
                         )
-
-                        OutputArea(viewModel = viewModel, modifier = Modifier.padding(top = 24.dp))
+                        OutputArea(
+                            viewModel = viewModel,
+                            modifier =
+                                Modifier.padding(top = 24.dp).sysuiResTag("bouncer_text_entry")
+                        )
                     }
                 }
                 else -> Unit
@@ -417,10 +424,9 @@
                     StatusMessage(
                         viewModel = viewModel.message,
                     )
-
                     OutputArea(
                         viewModel = viewModel,
-                        modifier = Modifier.padding(top = 24.dp).testTag("OutputArea")
+                        modifier = Modifier.padding(top = 24.dp).sysuiResTag("bouncer_text_entry")
                     )
                 }
             },
@@ -485,7 +491,6 @@
                 StatusMessage(
                     viewModel = viewModel.message,
                 )
-
                 OutputArea(viewModel = viewModel, modifier = Modifier.padding(top = 24.dp))
 
                 InputArea(
@@ -654,17 +659,16 @@
 ) {
     val authMethodViewModel: AuthMethodBouncerViewModel? by
         viewModel.authMethodViewModel.collectAsStateWithLifecycle()
-
     when (val nonNullViewModel = authMethodViewModel) {
         is PinBouncerViewModel ->
             PinInputDisplay(
                 viewModel = nonNullViewModel,
-                modifier = modifier,
+                modifier = modifier.sysuiResTag("bouncer_text_entry")
             )
         is PasswordBouncerViewModel ->
             PasswordBouncer(
                 viewModel = nonNullViewModel,
-                modifier = modifier,
+                modifier = modifier.sysuiResTag("bouncer_text_entry")
             )
         else -> Unit
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
index c5bb33c..7fb88e8 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
@@ -27,8 +27,8 @@
 import com.android.compose.animation.scene.UserAction
 import com.android.compose.animation.scene.UserActionResult
 import com.android.systemui.bouncer.ui.BouncerDialogFactory
-import com.android.systemui.bouncer.ui.viewmodel.BouncerSceneActionsViewModel
 import com.android.systemui.bouncer.ui.viewmodel.BouncerSceneContentViewModel
+import com.android.systemui.bouncer.ui.viewmodel.BouncerUserActionsViewModel
 import com.android.systemui.compose.modifiers.sysuiResTag
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.lifecycle.ExclusiveActivatable
@@ -54,18 +54,17 @@
 class BouncerScene
 @Inject
 constructor(
-    private val actionsViewModelFactory: BouncerSceneActionsViewModel.Factory,
+    private val actionsViewModelFactory: BouncerUserActionsViewModel.Factory,
     private val contentViewModelFactory: BouncerSceneContentViewModel.Factory,
     private val dialogFactory: BouncerDialogFactory,
 ) : ExclusiveActivatable(), Scene {
     override val key = Scenes.Bouncer
 
-    private val actionsViewModel: BouncerSceneActionsViewModel by lazy {
+    private val actionsViewModel: BouncerUserActionsViewModel by lazy {
         actionsViewModelFactory.create()
     }
 
-    override val destinationScenes: Flow<Map<UserAction, UserActionResult>> =
-        actionsViewModel.actions
+    override val userActions: Flow<Map<UserAction, UserActionResult>> = actionsViewModel.actions
 
     override suspend fun onActivated(): Nothing {
         actionsViewModel.activate()
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
index 4ec0d99..480e4e4 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
@@ -93,11 +93,15 @@
         }
     }
 
+    // set the focus, so adb can send the key events for testing.
+    val focusRequester = FocusRequester()
+    LaunchedEffect(Unit) { focusRequester.requestFocus() }
+
     VerticalGrid(
         columns = columns,
         verticalSpacing = verticalSpacing,
         horizontalSpacing = calculateHorizontalSpacingBetweenColumns(gridWidth = 300.dp),
-        modifier = modifier,
+        modifier = modifier.focusRequester(focusRequester)
     ) {
         repeat(9) { index ->
             DigitButton(
@@ -285,26 +289,26 @@
     Box(
         contentAlignment = Alignment.Center,
         modifier =
-        modifier
-            .focusRequester(FocusRequester.Default)
-            .focusable()
-            .sizeIn(maxWidth = pinButtonMaxSize, maxHeight = pinButtonMaxSize)
-            .aspectRatio(1f)
-            .drawBehind {
-                drawRoundRect(
-                    color = containerColor,
-                    cornerRadius = CornerRadius(cornerRadius.toPx()),
-                )
-            }
-            .clip(CircleShape)
-            .thenIf(isEnabled) {
-                Modifier.combinedClickable(
-                    interactionSource = interactionSource,
-                    indication = indication,
-                    onClick = onClicked,
-                    onLongClick = onLongPressed
-                )
-            },
+            modifier
+                .focusRequester(FocusRequester.Default)
+                .focusable()
+                .sizeIn(maxWidth = pinButtonMaxSize, maxHeight = pinButtonMaxSize)
+                .aspectRatio(1f)
+                .drawBehind {
+                    drawRoundRect(
+                        color = containerColor,
+                        cornerRadius = CornerRadius(cornerRadius.toPx()),
+                    )
+                }
+                .clip(CircleShape)
+                .thenIf(isEnabled) {
+                    Modifier.combinedClickable(
+                        interactionSource = interactionSource,
+                        indication = indication,
+                        onClick = onClicked,
+                        onLongClick = onLongPressed
+                    )
+                },
     ) {
         content(contentColor::value)
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt
index 465eade..ba885f7 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt
@@ -34,8 +34,10 @@
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.heightIn
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.wrapContentHeight
 import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Text
@@ -351,14 +353,17 @@
 
     @Composable
     fun Content(modifier: Modifier) {
-        Row(
-            modifier =
+
+        // Wrap PIN entry in a Box so it is visible to accessibility (even if empty).
+        Box(modifier = modifier.fillMaxWidth().wrapContentHeight()) {
+            Row(
                 modifier
                     .heightIn(min = shapeAnimations.shapeSize)
                     // Pins overflowing horizontally should still be shown as scrolling.
-                    .wrapContentSize(unbounded = true),
-        ) {
-            entries.forEach { entry -> key(entry.digit) { entry.Content() } }
+                    .wrapContentSize(unbounded = true)
+            ) {
+                entries.forEach { entry -> key(entry.digit) { entry.Content() } }
+            }
         }
     }
 
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt
index f658169..8b6de6a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt
@@ -49,10 +49,10 @@
 ) : ExclusiveActivatable(), Scene {
     override val key = Scenes.Communal
 
-    override val destinationScenes: Flow<Map<UserAction, UserActionResult>> =
-        MutableStateFlow<Map<UserAction, UserActionResult>>(
+    override val userActions: Flow<Map<UserAction, UserActionResult>> =
+        MutableStateFlow(
                 mapOf(
-                    Swipe(SwipeDirection.End) to UserActionResult(Scenes.Lockscreen),
+                    Swipe(SwipeDirection.End) to Scenes.Lockscreen,
                 )
             )
             .asStateFlow()
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
index 5f600d3..c7c29f9 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
@@ -24,7 +24,7 @@
 import com.android.compose.animation.scene.UserActionResult
 import com.android.compose.animation.scene.animateContentFloatAsState
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneActionsViewModel
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenUserActionsViewModel
 import com.android.systemui.lifecycle.ExclusiveActivatable
 import com.android.systemui.qs.ui.composable.QuickSettings
 import com.android.systemui.scene.shared.model.Scenes
@@ -38,17 +38,16 @@
 class LockscreenScene
 @Inject
 constructor(
-    actionsViewModelFactory: LockscreenSceneActionsViewModel.Factory,
+    actionsViewModelFactory: LockscreenUserActionsViewModel.Factory,
     private val lockscreenContent: Lazy<LockscreenContent>,
 ) : ExclusiveActivatable(), Scene {
     override val key = Scenes.Lockscreen
 
-    private val actionsViewModel: LockscreenSceneActionsViewModel by lazy {
+    private val actionsViewModel: LockscreenUserActionsViewModel by lazy {
         actionsViewModelFactory.create()
     }
 
-    override val destinationScenes: Flow<Map<UserAction, UserActionResult>> =
-        actionsViewModel.actions
+    override val userActions: Flow<Map<UserAction, UserActionResult>> = actionsViewModel.actions
 
     override suspend fun onActivated(): Nothing {
         actionsViewModel.activate()
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt
index e4c611e..a22becc 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt
@@ -23,6 +23,8 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
 import com.android.compose.animation.scene.ContentScope
+import com.android.compose.animation.scene.UserAction
+import com.android.compose.animation.scene.UserActionResult
 import com.android.systemui.battery.BatteryMeterViewController
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.lifecycle.rememberViewModel
@@ -39,6 +41,7 @@
 import com.android.systemui.statusbar.phone.ui.TintedIconManager
 import dagger.Lazy
 import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
 
 @SysUISingleton
 class NotificationsShadeOverlay
@@ -59,6 +62,8 @@
         actionsViewModelFactory.create()
     }
 
+    override val userActions: Flow<Map<UserAction, UserActionResult>> = actionsViewModel.actions
+
     override suspend fun activate(): Nothing {
         actionsViewModel.activate()
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeScene.kt
index ea3f066..1f4cd04 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeScene.kt
@@ -29,7 +29,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.lifecycle.ExclusiveActivatable
 import com.android.systemui.lifecycle.rememberViewModel
-import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeSceneActionsViewModel
+import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeUserActionsViewModel
 import com.android.systemui.scene.session.ui.composable.SaveableSession
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.composable.Scene
@@ -49,7 +49,7 @@
 class NotificationsShadeScene
 @Inject
 constructor(
-    private val actionsViewModelFactory: NotificationsShadeSceneActionsViewModel.Factory,
+    private val actionsViewModelFactory: NotificationsShadeUserActionsViewModel.Factory,
     private val shadeHeaderViewModelFactory: ShadeHeaderViewModel.Factory,
     private val notificationsPlaceholderViewModelFactory: NotificationsPlaceholderViewModel.Factory,
     private val tintedIconManagerFactory: TintedIconManager.Factory,
@@ -61,12 +61,11 @@
 
     override val key = Scenes.NotificationsShade
 
-    private val actionsViewModel: NotificationsShadeSceneActionsViewModel by lazy {
+    private val actionsViewModel: NotificationsShadeUserActionsViewModel by lazy {
         actionsViewModelFactory.create()
     }
 
-    override val destinationScenes: Flow<Map<UserAction, UserActionResult>> =
-        actionsViewModel.actions
+    override val userActions: Flow<Map<UserAction, UserActionResult>> = actionsViewModel.actions
 
     override suspend fun onActivated(): Nothing {
         actionsViewModel.activate()
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
index 373383f..d34295e 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
@@ -93,8 +93,8 @@
 import com.android.systemui.qs.footer.ui.compose.FooterActionsWithAnimatedVisibility
 import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaLandscapeTopOffset
 import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaOffset.InQS
-import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneActionsViewModel
 import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneContentViewModel
+import com.android.systemui.qs.ui.viewmodel.QuickSettingsUserActionsViewModel
 import com.android.systemui.res.R
 import com.android.systemui.scene.session.ui.composable.SaveableSession
 import com.android.systemui.scene.shared.model.Scenes
@@ -125,7 +125,7 @@
     private val shadeSession: SaveableSession,
     private val notificationStackScrollView: Lazy<NotificationScrollView>,
     private val notificationsPlaceholderViewModelFactory: NotificationsPlaceholderViewModel.Factory,
-    private val actionsViewModelFactory: QuickSettingsSceneActionsViewModel.Factory,
+    private val actionsViewModelFactory: QuickSettingsUserActionsViewModel.Factory,
     private val contentViewModelFactory: QuickSettingsSceneContentViewModel.Factory,
     private val tintedIconManagerFactory: TintedIconManager.Factory,
     private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory,
@@ -135,12 +135,11 @@
 ) : ExclusiveActivatable(), Scene {
     override val key = Scenes.QuickSettings
 
-    private val actionsViewModel: QuickSettingsSceneActionsViewModel by lazy {
+    private val actionsViewModel: QuickSettingsUserActionsViewModel by lazy {
         actionsViewModelFactory.create()
     }
 
-    override val destinationScenes: Flow<Map<UserAction, UserActionResult>> =
-        actionsViewModel.actions
+    override val userActions: Flow<Map<UserAction, UserActionResult>> = actionsViewModel.actions
 
     override suspend fun onActivated(): Nothing {
         actionsViewModel.activate()
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
index 988c712..f8d0588 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
@@ -34,6 +34,8 @@
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.compose.animation.scene.ContentScope
+import com.android.compose.animation.scene.UserAction
+import com.android.compose.animation.scene.UserActionResult
 import com.android.systemui.battery.BatteryMeterViewController
 import com.android.systemui.brightness.ui.compose.BrightnessSliderContainer
 import com.android.systemui.compose.modifiers.sysuiResTag
@@ -51,6 +53,7 @@
 import com.android.systemui.statusbar.phone.ui.StatusBarIconController
 import com.android.systemui.statusbar.phone.ui.TintedIconManager
 import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
 
 @SysUISingleton
 class QuickSettingsShadeOverlay
@@ -69,6 +72,8 @@
         actionsViewModelFactory.create()
     }
 
+    override val userActions: Flow<Map<UserAction, UserActionResult>> = actionsViewModel.actions
+
     override suspend fun activate(): Nothing {
         actionsViewModel.activate()
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt
index 9316eb9..e27c7e2 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt
@@ -27,8 +27,8 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.lifecycle.ExclusiveActivatable
 import com.android.systemui.lifecycle.rememberViewModel
-import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeSceneActionsViewModel
 import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeSceneContentViewModel
+import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeUserActionsViewModel
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.composable.Scene
 import com.android.systemui.shade.ui.composable.ExpandedShadeHeader
@@ -43,7 +43,7 @@
 class QuickSettingsShadeScene
 @Inject
 constructor(
-    private val actionsViewModelFactory: QuickSettingsShadeSceneActionsViewModel.Factory,
+    private val actionsViewModelFactory: QuickSettingsShadeUserActionsViewModel.Factory,
     private val contentViewModelFactory: QuickSettingsShadeSceneContentViewModel.Factory,
     private val shadeHeaderViewModelFactory: ShadeHeaderViewModel.Factory,
     private val tintedIconManagerFactory: TintedIconManager.Factory,
@@ -53,12 +53,11 @@
 
     override val key = Scenes.QuickSettingsShade
 
-    private val actionsViewModel: QuickSettingsShadeSceneActionsViewModel by lazy {
+    private val actionsViewModel: QuickSettingsShadeUserActionsViewModel by lazy {
         actionsViewModelFactory.create()
     }
 
-    override val destinationScenes: Flow<Map<UserAction, UserActionResult>> =
-        actionsViewModel.actions
+    override val userActions: Flow<Map<UserAction, UserActionResult>> = actionsViewModel.actions
 
     override suspend fun onActivated(): Nothing {
         actionsViewModel.activate()
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/ActionableContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/ActionableContent.kt
new file mode 100644
index 0000000..8fe6893
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/ActionableContent.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.scene.ui.composable
+
+import com.android.compose.animation.scene.UserAction
+import com.android.compose.animation.scene.UserActionResult
+import kotlinx.coroutines.flow.Flow
+
+/** Defines interface for content that can respond to user-actions. */
+interface ActionableContent {
+    /**
+     * The mapping between [UserAction] and destination [UserActionResult]s.
+     *
+     * When the scene framework detects a user action, if the current scene has a map entry for that
+     * user action, the framework starts a transition to the content specified in the map.
+     *
+     * Once the content is shown, the scene framework will read this property and set up a collector
+     * to watch for new mapping values. For each map entry, the scene framework will set up user
+     * input handling for its [UserAction] and, if such a user action is detected, initiate a
+     * transition to the specified [UserActionResult].
+     *
+     * Note that reading from this method does _not_ mean that any user action has occurred.
+     * Instead, the property is read before any user action/gesture is detected so that the
+     * framework can decide whether to set up gesture/input detectors/listeners in case user actions
+     * of the given types ever occur.
+     *
+     * A missing value for a specific [UserAction] means that the user action of the given type is
+     * not currently active in the top-most content (in z-index order) and should be ignored by the
+     * framework until the top-most content changes.
+     */
+    val userActions: Flow<Map<UserAction, UserActionResult>>
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
index 6fb4724..ae5dd8a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
@@ -33,7 +33,7 @@
 import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaLandscapeTopOffset
 import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaOffset.Default
 import com.android.systemui.scene.shared.model.Scenes
-import com.android.systemui.scene.ui.viewmodel.GoneSceneActionsViewModel
+import com.android.systemui.scene.ui.viewmodel.GoneUserActionsViewModel
 import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
 import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
 import dagger.Lazy
@@ -50,14 +50,13 @@
 constructor(
     private val notificationStackScrolLView: Lazy<NotificationScrollView>,
     private val notificationsPlaceholderViewModelFactory: NotificationsPlaceholderViewModel.Factory,
-    private val viewModelFactory: GoneSceneActionsViewModel.Factory,
+    private val viewModelFactory: GoneUserActionsViewModel.Factory,
 ) : ExclusiveActivatable(), Scene {
     override val key = Scenes.Gone
 
-    private val actionsViewModel: GoneSceneActionsViewModel by lazy { viewModelFactory.create() }
+    private val actionsViewModel: GoneUserActionsViewModel by lazy { viewModelFactory.create() }
 
-    override val destinationScenes: Flow<Map<UserAction, UserActionResult>> =
-        actionsViewModel.actions
+    override val userActions: Flow<Map<UserAction, UserActionResult>> = actionsViewModel.actions
 
     override suspend fun onActivated(): Nothing {
         actionsViewModel.activate()
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/Overlay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/Overlay.kt
index d62befd..609ce90 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/Overlay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/Overlay.kt
@@ -18,9 +18,14 @@
 
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
+import com.android.compose.animation.scene.Back
 import com.android.compose.animation.scene.ContentScope
 import com.android.compose.animation.scene.OverlayKey
+import com.android.compose.animation.scene.UserAction
+import com.android.compose.animation.scene.UserActionResult
 import com.android.systemui.lifecycle.Activatable
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
 
 /**
  * Defines interface for classes that can describe an "overlay".
@@ -29,9 +34,17 @@
  * container takes care of rendering any current overlays and allowing overlays to be shown, hidden,
  * or replaced based on a user action.
  */
-interface Overlay : Activatable {
+interface Overlay : Activatable, ActionableContent {
     /** Uniquely-identifying key for this overlay. The key must be unique within its container. */
     val key: OverlayKey
 
+    /**
+     * The user actions supported by this overlay.
+     *
+     * @see [ActionableContent.userActions]
+     */
+    override val userActions: Flow<Map<UserAction, UserActionResult>>
+        get() = flowOf(mapOf(Back to UserActionResult.HideOverlay(key)))
+
     @Composable fun ContentScope.Content(modifier: Modifier)
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/Scene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/Scene.kt
index 5319ec3..8d8ab8e 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/Scene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/Scene.kt
@@ -20,10 +20,7 @@
 import androidx.compose.ui.Modifier
 import com.android.compose.animation.scene.SceneKey
 import com.android.compose.animation.scene.SceneScope
-import com.android.compose.animation.scene.UserAction
-import com.android.compose.animation.scene.UserActionResult
 import com.android.systemui.lifecycle.Activatable
-import kotlinx.coroutines.flow.Flow
 
 /**
  * Defines interface for classes that can describe a "scene".
@@ -33,32 +30,10 @@
  * based on either user action (for example, swiping down while on the lock screen scene may switch
  * to the shade scene).
  */
-interface Scene : Activatable {
+interface Scene : Activatable, ActionableContent {
 
     /** Uniquely-identifying key for this scene. The key must be unique within its container. */
     val key: SceneKey
 
-    /**
-     * The mapping between [UserAction] and destination [UserActionResult]s.
-     *
-     * When the scene framework detects a user action, if the current scene has a map entry for that
-     * user action, the framework starts a transition to the scene in the map.
-     *
-     * Once the [Scene] becomes the current one, the scene framework will read this property and set
-     * up a collector to watch for new mapping values. If every map entry provided by the scene, the
-     * framework will set up user input handling for its [UserAction] and, if such a user action is
-     * detected, initiate a transition to the specified [UserActionResult].
-     *
-     * Note that reading from this method does _not_ mean that any user action has occurred.
-     * Instead, the property is read before any user action/gesture is detected so that the
-     * framework can decide whether to set up gesture/input detectors/listeners in case user actions
-     * of the given types ever occur.
-     *
-     * Note that a missing value for a specific [UserAction] means that the user action of the given
-     * type is not currently active in the scene and should be ignored by the framework, while the
-     * current scene is this one.
-     */
-    val destinationScenes: Flow<Map<UserAction, UserActionResult>>
-
     @Composable fun SceneScope.Content(modifier: Modifier)
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
index 851fa3f..a7e41ce 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
@@ -104,7 +104,7 @@
     // TODO(b/359173565): Add overlay user actions when the API is final.
     LaunchedEffect(currentSceneKey) {
         try {
-            sceneByKey[currentSceneKey]?.destinationScenes?.collectLatest { userActions ->
+            sceneByKey[currentSceneKey]?.userActions?.collectLatest { userActions ->
                 userActionsByContentKey[currentSceneKey] =
                     viewModel.resolveSceneFamilies(userActions)
             }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
index 5fcf522..a03bf43 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -108,8 +108,8 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.composable.Scene
 import com.android.systemui.shade.shared.model.ShadeMode
-import com.android.systemui.shade.ui.viewmodel.ShadeSceneActionsViewModel
 import com.android.systemui.shade.ui.viewmodel.ShadeSceneContentViewModel
+import com.android.systemui.shade.ui.viewmodel.ShadeUserActionsViewModel
 import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
 import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
 import com.android.systemui.statusbar.phone.StatusBarLocation
@@ -154,7 +154,7 @@
 constructor(
     private val shadeSession: SaveableSession,
     private val notificationStackScrollView: Lazy<NotificationScrollView>,
-    private val actionsViewModelFactory: ShadeSceneActionsViewModel.Factory,
+    private val actionsViewModelFactory: ShadeUserActionsViewModel.Factory,
     private val contentViewModelFactory: ShadeSceneContentViewModel.Factory,
     private val notificationsPlaceholderViewModelFactory: NotificationsPlaceholderViewModel.Factory,
     private val tintedIconManagerFactory: TintedIconManager.Factory,
@@ -167,7 +167,7 @@
 
     override val key = Scenes.Shade
 
-    private val actionsViewModel: ShadeSceneActionsViewModel by lazy {
+    private val actionsViewModel: ShadeUserActionsViewModel by lazy {
         actionsViewModelFactory.create()
     }
 
@@ -175,8 +175,7 @@
         actionsViewModel.activate()
     }
 
-    override val destinationScenes: Flow<Map<UserAction, UserActionResult>> =
-        actionsViewModel.actions
+    override val userActions: Flow<Map<UserAction, UserActionResult>> = actionsViewModel.actions
 
     @Composable
     override fun SceneScope.Content(
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt
index 4aa50b5..b30f2b7 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt
@@ -399,26 +399,53 @@
 
         val fromValue = sharedValue[transition.fromContent]
         val toValue = sharedValue[transition.toContent]
-        return if (fromValue != null && toValue != null) {
-            if (fromValue == toValue) {
-                // Optimization: avoid reading progress if the values are the same, so we don't
-                // relayout/redraw for nothing.
-                fromValue
-            } else {
-                val overscrollSpec = transition.currentOverscrollSpec
-                val progress =
-                    when {
-                        overscrollSpec == null -> {
-                            if (canOverflow) transition.progress
-                            else transition.progress.fastCoerceIn(0f, 1f)
-                        }
-                        overscrollSpec.content == transition.toContent -> 1f
-                        else -> 0f
-                    }
+        if (fromValue == null && toValue == null) {
+            return null
+        }
 
-                sharedValue.type.lerp(fromValue, toValue, progress)
+        if (fromValue != null && toValue != null) {
+            return interpolateSharedValue(fromValue, toValue, transition, sharedValue)
+        }
+
+        if (transition is TransitionState.Transition.ReplaceOverlay) {
+            val currentSceneValue = sharedValue[transition.currentScene]
+            if (currentSceneValue != null) {
+                return interpolateSharedValue(
+                    fromValue = fromValue ?: currentSceneValue,
+                    toValue = toValue ?: currentSceneValue,
+                    transition,
+                    sharedValue,
+                )
             }
-        } else fromValue ?: toValue
+        }
+
+        return fromValue ?: toValue
+    }
+
+    private fun interpolateSharedValue(
+        fromValue: T,
+        toValue: T,
+        transition: TransitionState.Transition,
+        sharedValue: SharedValue<T, *>,
+    ): T? {
+        if (fromValue == toValue) {
+            // Optimization: avoid reading progress if the values are the same, so we don't
+            // relayout/redraw for nothing.
+            return fromValue
+        }
+
+        val overscrollSpec = transition.currentOverscrollSpec
+        val progress =
+            when {
+                overscrollSpec == null -> {
+                    if (canOverflow) transition.progress
+                    else transition.progress.fastCoerceIn(0f, 1f)
+                }
+                overscrollSpec.content == transition.toContent -> 1f
+                else -> 0f
+            }
+
+        return sharedValue.type.lerp(fromValue, toValue, progress)
     }
 
     private fun transition(sharedValue: SharedValue<T, Delta>): TransitionState.Transition? {
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
index 9b1740d..56c08b9 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
@@ -313,10 +313,27 @@
         // If this element is not supposed to be laid out now, either because it is not part of any
         // ongoing transition or the other content of its transition is overscrolling, then lay out
         // the element normally and don't place it.
-        val overscrollScene = transition?.currentOverscrollSpec?.content
-        val isOtherSceneOverscrolling = overscrollScene != null && overscrollScene != content.key
-        if (isOtherSceneOverscrolling) {
-            return doNotPlace(measurable, constraints)
+        val overscrollContent = transition?.currentOverscrollSpec?.content
+        if (overscrollContent != null && overscrollContent != content.key) {
+            when (transition) {
+                is TransitionState.Transition.ChangeScene ->
+                    return doNotPlace(measurable, constraints)
+
+                // If we are overscrolling an overlay that does not contain an element that is in
+                // the current scene, place it in that scene otherwise the element won't be placed
+                // at all.
+                is TransitionState.Transition.ShowOrHideOverlay,
+                is TransitionState.Transition.ReplaceOverlay -> {
+                    if (
+                        content.key == transition.currentScene &&
+                            overscrollContent !in element.stateByContent
+                    ) {
+                        return placeNormally(measurable, constraints)
+                    } else {
+                        return doNotPlace(measurable, constraints)
+                    }
+                }
+            }
         }
 
         val placeable =
@@ -836,19 +853,32 @@
         content,
         element.key,
         transition,
+        isInContent = { it in element.stateByContent },
     )
 }
 
-internal fun shouldPlaceOrComposeSharedElement(
+internal inline fun shouldPlaceOrComposeSharedElement(
     layoutImpl: SceneTransitionLayoutImpl,
     content: ContentKey,
     element: ElementKey,
     transition: TransitionState.Transition,
+    isInContent: (ContentKey) -> Boolean,
 ): Boolean {
-    // If we are overscrolling, only place/compose the element in the overscrolling scene.
-    val overscrollScene = transition.currentOverscrollSpec?.content
-    if (overscrollScene != null) {
-        return content == overscrollScene
+    val overscrollContent = transition.currentOverscrollSpec?.content
+    if (overscrollContent != null) {
+        return when (transition) {
+            // If we are overscrolling between scenes, only place/compose the element in the
+            // overscrolling scene.
+            is TransitionState.Transition.ChangeScene -> content == overscrollContent
+
+            // If we are overscrolling an overlay, place/compose the element if [content] is the
+            // overscrolling content or if [content] is the current scene and the overscrolling
+            // overlay does not contain the element.
+            is TransitionState.Transition.ReplaceOverlay,
+            is TransitionState.Transition.ShowOrHideOverlay ->
+                content == overscrollContent ||
+                    (content == transition.currentScene && !isInContent(overscrollContent))
+        }
     }
 
     val scenePicker = element.contentPicker
@@ -1230,17 +1260,30 @@
     // elements follow the finger direction.
     val isSharedElement = fromState != null && toState != null
     if (isSharedElement && isSharedElementEnabled(element.key, transition)) {
-        val start = contentValue(fromState!!)
-        val end = contentValue(toState!!)
+        return interpolateSharedElement(
+            transition = transition,
+            contentValue = contentValue,
+            fromState = fromState!!,
+            toState = toState!!,
+            isSpecified = isSpecified,
+            lerp = lerp,
+        )
+    }
 
-        // TODO(b/316901148): Remove checks to isSpecified() once the lookahead pass runs for all
-        // nodes before the intermediate layout pass.
-        if (!isSpecified(start)) return end
-        if (!isSpecified(end)) return start
-
-        // Make sure we don't read progress if values are the same and we don't need to interpolate,
-        // so we don't invalidate the phase where this is read.
-        return if (start == end) start else lerp(start, end, transition.progress)
+    // If we are replacing an overlay and the element is both in a single overlay and in the current
+    // scene, interpolate the state of the element using the current scene as the other scene.
+    if (!isSharedElement && transition is TransitionState.Transition.ReplaceOverlay) {
+        val currentSceneState = element.stateByContent[transition.currentScene]
+        if (currentSceneState != null) {
+            return interpolateSharedElement(
+                transition = transition,
+                contentValue = contentValue,
+                fromState = fromState ?: currentSceneState,
+                toState = toState ?: currentSceneState,
+                isSpecified = isSpecified,
+                lerp = lerp,
+            )
+        }
     }
 
     // Get the transformed value, i.e. the target value at the beginning (for entering elements) or
@@ -1383,3 +1426,24 @@
         lerp(idleValue, targetValue, rangeProgress)
     }
 }
+
+private inline fun <T> interpolateSharedElement(
+    transition: TransitionState.Transition,
+    contentValue: (Element.State) -> T,
+    fromState: Element.State,
+    toState: Element.State,
+    isSpecified: (T) -> Boolean,
+    lerp: (T, T, Float) -> T
+): T {
+    val start = contentValue(fromState)
+    val end = contentValue(toState)
+
+    // TODO(b/316901148): Remove checks to isSpecified() once the lookahead pass runs for all
+    // nodes before the intermediate layout pass.
+    if (!isSpecified(start)) return end
+    if (!isSpecified(end)) return start
+
+    // Make sure we don't read progress if values are the same and we don't need to interpolate,
+    // so we don't invalidate the phase where this is read.
+    return if (start == end) start else lerp(start, end, transition.progress)
+}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
index 715222c..471ad3f 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
@@ -194,11 +194,13 @@
         is TransitionState.Transition -> {
             // During transitions, always compose movable elements in the scene picked by their
             // content picker.
+            val contents = element.contentPicker.contents
             shouldPlaceOrComposeSharedElement(
                 layoutImpl,
                 content,
                 element,
                 elementState,
+                isInContent = { contents.contains(it) }
             )
         }
     }
@@ -208,8 +210,8 @@
     element: MovableElementKey,
     transitionStates: List<TransitionState>,
 ): TransitionState? {
-    val content = element.contentPicker.contents
-    return elementState(transitionStates, isInContent = { content.contains(it) })
+    val contents = element.contentPicker.contents
+    return elementState(transitionStates, isInContent = { contents.contains(it) })
 }
 
 private fun movableElementContentWhenIdle(
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
index 094f20e..061613f 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
@@ -550,6 +550,22 @@
              */
             requiresFullDistanceSwipe: Boolean = false,
         ): UserActionResult = ChangeScene(toScene, transitionKey, requiresFullDistanceSwipe)
+
+        /** A [UserActionResult] that shows [toOverlay]. */
+        operator fun invoke(
+            /** The overlay we should be transitioning to during the [UserAction]. */
+            toOverlay: OverlayKey,
+
+            /** The key of the transition that should be used. */
+            transitionKey: TransitionKey? = null,
+
+            /**
+             * If `true`, the swipe will be committed if only if the user swiped at least the swipe
+             * distance, i.e. the transition progress was already equal to or bigger than 100% when
+             * the user released their finger.
+             */
+            requiresFullDistanceSwipe: Boolean = false,
+        ): UserActionResult = ShowOverlay(toOverlay, transitionKey, requiresFullDistanceSwipe)
     }
 }
 
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt
index bec2bb2..471362b 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt
@@ -18,14 +18,17 @@
 
 import androidx.compose.animation.core.LinearEasing
 import androidx.compose.animation.core.tween
+import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.size
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
+import androidx.compose.runtime.snapshotFlow
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.testTag
@@ -42,7 +45,12 @@
 import com.android.compose.animation.scene.TestOverlays.OverlayB
 import com.android.compose.animation.scene.TestScenes.SceneA
 import com.android.compose.test.assertSizeIsEqualTo
+import com.android.compose.test.setContentAndCreateMainScope
+import com.android.compose.test.subjects.assertThat
+import com.android.compose.test.transition
+import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -524,4 +532,162 @@
             }
         }
     }
+
+    @Test
+    fun replaceAnimation_elementInCurrentSceneAndOneOverlay() {
+        val sharedIntKey = ValueKey("sharedInt")
+        val sharedIntValueByContent = mutableMapOf<ContentKey, Int>()
+
+        @Composable
+        fun SceneScope.animateContentInt(targetValue: Int) {
+            val animatedValue = animateContentIntAsState(targetValue, sharedIntKey)
+            LaunchedEffect(animatedValue) {
+                try {
+                    snapshotFlow { animatedValue.value }
+                        .collect { sharedIntValueByContent[contentKey] = it }
+                } finally {
+                    sharedIntValueByContent.remove(contentKey)
+                }
+            }
+        }
+
+        rule.testReplaceOverlayTransition(
+            currentSceneContent = {
+                Box(Modifier.size(width = 180.dp, height = 120.dp)) {
+                    animateContentInt(targetValue = 1_000)
+                    Foo(width = 60.dp, height = 40.dp)
+                }
+            },
+            fromContent = {},
+            fromAlignment = Alignment.TopStart,
+            toContent = {
+                animateContentInt(targetValue = 2_000)
+                Foo(width = 100.dp, height = 80.dp)
+            },
+            transition = {
+                // 4 frames of animation
+                spec = tween(4 * 16, easing = LinearEasing)
+            },
+        ) {
+            // Foo moves from (0,0) with a size of 60x40dp to centered (in a 180x120dp Box) with a
+            // size of 100x80dp, so at (40,20).
+            //
+            // The animated Int goes from 1_000 to 2_000.
+            before {
+                rule
+                    .onNode(isElement(TestElements.Foo, content = SceneA))
+                    .assertSizeIsEqualTo(60.dp, 40.dp)
+                    .assertPositionInRootIsEqualTo(0.dp, 0.dp)
+                rule.onNode(isElement(TestElements.Foo, content = OverlayA)).assertDoesNotExist()
+                rule.onNode(isElement(TestElements.Foo, content = OverlayB)).assertDoesNotExist()
+
+                assertThat(sharedIntValueByContent).containsEntry(SceneA, 1_000)
+                assertThat(sharedIntValueByContent).doesNotContainKey(OverlayA)
+                assertThat(sharedIntValueByContent).doesNotContainKey(OverlayB)
+            }
+
+            at(16) {
+                rule
+                    .onNode(isElement(TestElements.Foo, content = SceneA))
+                    .assertExists()
+                    .assertIsNotDisplayed()
+                rule.onNode(isElement(TestElements.Foo, content = OverlayA)).assertDoesNotExist()
+                rule
+                    .onNode(isElement(TestElements.Foo, content = OverlayB))
+                    .assertSizeIsEqualTo(70.dp, 50.dp)
+                    .assertPositionInRootIsEqualTo(10.dp, 5.dp)
+
+                assertThat(sharedIntValueByContent).containsEntry(SceneA, 1_250)
+                assertThat(sharedIntValueByContent).doesNotContainKey(OverlayA)
+                assertThat(sharedIntValueByContent).containsEntry(OverlayB, 1_250)
+            }
+
+            at(32) {
+                rule
+                    .onNode(isElement(TestElements.Foo, content = SceneA))
+                    .assertExists()
+                    .assertIsNotDisplayed()
+                rule.onNode(isElement(TestElements.Foo, content = OverlayA)).assertDoesNotExist()
+                rule
+                    .onNode(isElement(TestElements.Foo, content = OverlayB))
+                    .assertSizeIsEqualTo(80.dp, 60.dp)
+                    .assertPositionInRootIsEqualTo(20.dp, 10.dp)
+
+                assertThat(sharedIntValueByContent).containsEntry(SceneA, 1_500)
+                assertThat(sharedIntValueByContent).doesNotContainKey(OverlayA)
+                assertThat(sharedIntValueByContent).containsEntry(OverlayB, 1_500)
+            }
+
+            at(48) {
+                rule
+                    .onNode(isElement(TestElements.Foo, content = SceneA))
+                    .assertExists()
+                    .assertIsNotDisplayed()
+                rule.onNode(isElement(TestElements.Foo, content = OverlayA)).assertDoesNotExist()
+                rule
+                    .onNode(isElement(TestElements.Foo, content = OverlayB))
+                    .assertSizeIsEqualTo(90.dp, 70.dp)
+                    .assertPositionInRootIsEqualTo(30.dp, 15.dp)
+
+                assertThat(sharedIntValueByContent).containsEntry(SceneA, 1_750)
+                assertThat(sharedIntValueByContent).doesNotContainKey(OverlayA)
+                assertThat(sharedIntValueByContent).containsEntry(OverlayB, 1_750)
+            }
+
+            after {
+                rule
+                    .onNode(isElement(TestElements.Foo, content = SceneA))
+                    .assertExists()
+                    .assertIsNotDisplayed()
+                rule.onNode(isElement(TestElements.Foo, content = OverlayA)).assertDoesNotExist()
+                rule
+                    .onNode(isElement(TestElements.Foo, content = OverlayB))
+                    .assertSizeIsEqualTo(100.dp, 80.dp)
+                    .assertPositionInRootIsEqualTo(40.dp, 20.dp)
+
+                // Outside of transitions, the value is equal to the target value in each content.
+                assertThat(sharedIntValueByContent).containsEntry(SceneA, 1_000)
+                assertThat(sharedIntValueByContent).doesNotContainKey(OverlayA)
+                assertThat(sharedIntValueByContent).containsEntry(OverlayB, 2_000)
+            }
+        }
+    }
+
+    @Test
+    fun overscrollingOverlay_movableElementNotInOverlay() {
+        val state =
+            rule.runOnUiThread {
+                MutableSceneTransitionLayoutStateImpl(
+                    SceneA,
+                    transitions {
+                        // Make OverlayA overscrollable.
+                        overscroll(OverlayA, orientation = Orientation.Horizontal) {
+                            translate(ElementKey("elementThatDoesNotExist"), x = 10.dp)
+                        }
+                    }
+                )
+            }
+
+        val key = MovableElementKey("Foo", contents = setOf(SceneA))
+        val movableElementChildTag = "movableElementChildTag"
+        val scope =
+            rule.setContentAndCreateMainScope {
+                SceneTransitionLayout(state) {
+                    scene(SceneA) {
+                        MovableElement(key, Modifier) {
+                            content { Box(Modifier.testTag(movableElementChildTag).size(100.dp)) }
+                        }
+                    }
+                    overlay(OverlayA) { /* Does not contain the element. */ }
+                }
+            }
+
+        // Overscroll on Overlay A.
+        scope.launch { state.startTransition(transition(SceneA, OverlayA, progress = { 1.5f })) }
+        rule
+            .onNode(hasTestTag(movableElementChildTag) and inContent(SceneA))
+            .assertPositionInRootIsEqualTo(0.dp, 0.dp)
+            .assertSizeIsEqualTo(100.dp)
+            .assertIsDisplayed()
+    }
 }
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
index cd20a29a..d356c25 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
@@ -32,7 +32,7 @@
 import com.android.compose.animation.scene.transition.link.StateLink
 import com.android.compose.animation.scene.transition.seekToScene
 import com.android.compose.test.MonotonicClockTestScope
-import com.android.compose.test.TestTransition
+import com.android.compose.test.TestSceneTransition
 import com.android.compose.test.runMonotonicClockTest
 import com.android.compose.test.transition
 import com.google.common.truth.Truth.assertThat
@@ -556,8 +556,8 @@
 
     @Test
     fun multipleTransitions() = runTest {
-        val frozenTransitions = mutableSetOf<TestTransition>()
-        fun onFreezeAndAnimate(transition: TestTransition): () -> Unit {
+        val frozenTransitions = mutableSetOf<TestSceneTransition>()
+        fun onFreezeAndAnimate(transition: TestSceneTransition): () -> Unit {
             // Instead of letting the transition finish when it is frozen, we put the transition in
             // the frozenTransitions set so that we can verify that freezeAndAnimateToCurrentState()
             // is called when expected and then we call finish() ourselves to finish the
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestTransition.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestOverlayTransition.kt
similarity index 77%
copy from packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestTransition.kt
copy to packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestOverlayTransition.kt
index a6a83ee..646cff8 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestTransition.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestOverlayTransition.kt
@@ -18,18 +18,26 @@
 
 import androidx.compose.foundation.gestures.Orientation
 import com.android.compose.animation.scene.ContentKey
+import com.android.compose.animation.scene.OverlayKey
 import com.android.compose.animation.scene.SceneKey
 import com.android.compose.animation.scene.SceneTransitionLayoutImpl
 import com.android.compose.animation.scene.content.state.TransitionState
 import com.android.compose.animation.scene.content.state.TransitionState.Transition
 import kotlinx.coroutines.CompletableDeferred
 
-/** A transition for tests that will be finished once [finish] is called. */
-abstract class TestTransition(
+/** A [Transition.ShowOrHideOverlay] for tests that will be finished once [finish] is called. */
+abstract class TestOverlayTransition(
     fromScene: SceneKey,
-    toScene: SceneKey,
+    overlay: OverlayKey,
     replacedTransition: Transition?,
-) : Transition.ChangeScene(fromScene, toScene, replacedTransition) {
+) :
+    Transition.ShowOrHideOverlay(
+        overlay = overlay,
+        fromOrToScene = fromScene,
+        fromContent = fromScene,
+        toContent = overlay,
+        replacedTransition = replacedTransition,
+    ) {
     private val finishCompletable = CompletableDeferred<Unit>()
 
     override suspend fun run() {
@@ -42,11 +50,11 @@
     }
 }
 
-/** A utility to easily create a [TestTransition] in tests. */
+/** A utility to easily create a [TestOverlayTransition] in tests. */
 fun transition(
-    from: SceneKey,
-    to: SceneKey,
-    current: () -> SceneKey = { to },
+    fromScene: SceneKey,
+    overlay: OverlayKey,
+    isEffectivelyShown: () -> Boolean = { true },
     progress: () -> Float = { 0f },
     progressVelocity: () -> Float = { 0f },
     previewProgress: () -> Float = { 0f },
@@ -58,13 +66,14 @@
     isUpOrLeft: Boolean = false,
     bouncingContent: ContentKey? = null,
     orientation: Orientation = Orientation.Horizontal,
-    onFreezeAndAnimate: ((TestTransition) -> Unit)? = null,
+    onFreezeAndAnimate: ((TestOverlayTransition) -> Unit)? = null,
     replacedTransition: Transition? = null,
-): TestTransition {
+): TestOverlayTransition {
     return object :
-        TestTransition(from, to, replacedTransition), TransitionState.HasOverscrollProperties {
-        override val currentScene: SceneKey
-            get() = current()
+        TestOverlayTransition(fromScene, overlay, replacedTransition),
+        TransitionState.HasOverscrollProperties {
+        override val isEffectivelyShown: Boolean
+            get() = isEffectivelyShown()
 
         override val progress: Float
             get() = progress()
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestTransition.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestSceneTransition.kt
similarity index 89%
rename from packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestTransition.kt
rename to packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestSceneTransition.kt
index a6a83ee..d24b895 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestTransition.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestSceneTransition.kt
@@ -24,8 +24,8 @@
 import com.android.compose.animation.scene.content.state.TransitionState.Transition
 import kotlinx.coroutines.CompletableDeferred
 
-/** A transition for tests that will be finished once [finish] is called. */
-abstract class TestTransition(
+/** A [Transition.ChangeScene] for tests that will be finished once [finish] is called. */
+abstract class TestSceneTransition(
     fromScene: SceneKey,
     toScene: SceneKey,
     replacedTransition: Transition?,
@@ -42,7 +42,7 @@
     }
 }
 
-/** A utility to easily create a [TestTransition] in tests. */
+/** A utility to easily create a [TestSceneTransition] in tests. */
 fun transition(
     from: SceneKey,
     to: SceneKey,
@@ -58,11 +58,11 @@
     isUpOrLeft: Boolean = false,
     bouncingContent: ContentKey? = null,
     orientation: Orientation = Orientation.Horizontal,
-    onFreezeAndAnimate: ((TestTransition) -> Unit)? = null,
+    onFreezeAndAnimate: ((TestSceneTransition) -> Unit)? = null,
     replacedTransition: Transition? = null,
-): TestTransition {
+): TestSceneTransition {
     return object :
-        TestTransition(from, to, replacedTransition), TransitionState.HasOverscrollProperties {
+        TestSceneTransition(from, to, replacedTransition), TransitionState.HasOverscrollProperties {
         override val currentScene: SceneKey
             get() = current()
 
diff --git a/packages/SystemUI/docs/scene.md b/packages/SystemUI/docs/scene.md
index a7740c6..0ac15c5 100644
--- a/packages/SystemUI/docs/scene.md
+++ b/packages/SystemUI/docs/scene.md
@@ -124,8 +124,8 @@
 [`Scene`](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/Scene.kt)
 interface, which has three parts: 1. The `key` property returns the
 [`SceneKey`](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneKey.kt)
-that uniquely identifies that scene 2. The `destinationScenes` `Flow` returns
-the (potentially ever-changing) set of navigation edges to other scenes, based
+that uniquely identifies that scene 2. The `userActions` `Flow` returns
+the (potentially ever-changing) set of navigation edges to other content, based
 on user-actions, which is how the navigation graph is defined (see
 [the Scene navigation](#Scene-navigation) section for more) 3. The `Content`
 function which uses
@@ -141,7 +141,7 @@
 @SysUISingleton class YourScene @Inject constructor( /* your dependencies here */ ) : Scene {
     override val key = SceneKey.YourScene
 
-    override val destinationScenes: StateFlow<Map<UserAction, SceneModel>> =
+    override val userActions: StateFlow<Map<UserAction, SceneModel>> =
         MutableStateFlow<Map<UserAction, SceneModel>>(
             mapOf(
                 // This is where scene navigation is defined, more on that below.
diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
index 18ed22a..e444db4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
@@ -18,10 +18,8 @@
 package com.android.keyguard
 
 import android.app.admin.DevicePolicyManager
-import android.app.admin.flags.Flags as DevicePolicyFlags
 import android.content.res.Configuration
 import android.media.AudioManager
-import android.platform.test.annotations.EnableFlags
 import android.telephony.TelephonyManager
 import android.testing.TestableLooper.RunWithLooper
 import android.testing.TestableResources
@@ -942,7 +940,6 @@
     }
 
     @Test
-    @EnableFlags(DevicePolicyFlags.FLAG_HEADLESS_SINGLE_USER_FIXES)
     fun showAlmostAtWipeDialog_calledOnMainUser_setsCorrectUserType() {
         val mainUserId = 10
 
@@ -959,7 +956,6 @@
     }
 
     @Test
-    @EnableFlags(DevicePolicyFlags.FLAG_HEADLESS_SINGLE_USER_FIXES)
     fun showAlmostAtWipeDialog_calledOnNonMainUser_setsCorrectUserType() {
         val secondaryUserId = 10
         val mainUserId = 0
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
index 0c5e726..080b48a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
@@ -17,8 +17,6 @@
 package com.android.systemui.authentication.domain.interactor
 
 import android.app.admin.DevicePolicyManager
-import android.app.admin.flags.Flags as DevicePolicyFlags
-import android.platform.test.annotations.EnableFlags
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.widget.LockPatternUtils
@@ -414,7 +412,6 @@
         }
 
     @Test
-    @EnableFlags(DevicePolicyFlags.FLAG_HEADLESS_SINGLE_USER_FIXES)
     fun upcomingWipe() =
         testScope.runTest {
             val upcomingWipe by collectLastValue(underTest.upcomingWipe)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModelTest.kt
similarity index 93%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneActionsViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModelTest.kt
index a86a0c0..f58bbc3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModelTest.kt
@@ -44,17 +44,17 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @EnableSceneContainer
-class BouncerSceneActionsViewModelTest : SysuiTestCase() {
+class BouncerUserActionsViewModelTest : SysuiTestCase() {
 
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
 
-    private lateinit var underTest: BouncerSceneActionsViewModel
+    private lateinit var underTest: BouncerUserActionsViewModel
 
     @Before
     fun setUp() {
         kosmos.sceneContainerStartable.start()
-        underTest = kosmos.bouncerSceneActionsViewModel
+        underTest = kosmos.bouncerUserActionsViewModel
         underTest.activateIn(testScope)
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
index ec8cc4d..53d82d7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
@@ -34,8 +34,6 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.testing.FakeMetricsLogger;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.flags.FakeFeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
@@ -83,7 +81,6 @@
     private final FalsingClassifier.Result mPassedResult = FalsingClassifier.Result.passed(1);
     private final FalsingClassifier.Result mFalsedResult =
             FalsingClassifier.Result.falsed(1, getClass().getSimpleName(), "");
-    private final FakeFeatureFlags mFakeFeatureFlags = new FakeFeatureFlags();
 
     @Before
     public void setup() {
@@ -101,8 +98,7 @@
         mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider,
                 mMetricsLogger, mClassifiers, mSingleTapClassifier, mLongTapClassifier,
                 mDoubleTapClassifier, mHistoryTracker, mKeyguardStateController,
-                mAccessibilityManager, false, mFakeFeatureFlags);
-        mFakeFeatureFlags.set(Flags.FALSING_OFF_FOR_UNFOLDED, true);
+                mAccessibilityManager, false);
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
index 5e6ff73..7426574 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
@@ -233,7 +233,7 @@
             .thenReturn(dreamOverlayComponent)
 
         val ambientTouchComponent = mock<AmbientTouchComponent>()
-        whenever(ambientTouchComponentFactory.create(any(), any()))
+        whenever(ambientTouchComponentFactory.create(any(), any(), any()))
             .thenReturn(ambientTouchComponent)
         whenever(ambientTouchComponent.getTouchMonitor()).thenReturn(mTouchMonitor)
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
index ca15eff..34d926a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
@@ -24,6 +24,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.contextualeducation.GestureType
+import com.android.systemui.contextualeducation.GestureType.ALL_APPS
 import com.android.systemui.contextualeducation.GestureType.BACK
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.education.data.model.GestureEduModel
@@ -220,17 +221,19 @@
             verify(kosmos.mockEduInputManager)
                 .registerKeyGestureEventListener(any(), listenerCaptor.capture())
 
-            val backGestureEvent =
+            val allAppsKeyGestureEvent =
                 KeyGestureEvent(
                     /* deviceId= */ 1,
-                    intArrayOf(KeyEvent.KEYCODE_ESCAPE),
+                    IntArray(0),
                     KeyEvent.META_META_ON,
-                    KeyGestureEvent.KEY_GESTURE_TYPE_BACK
+                    KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS
                 )
-            listenerCaptor.value.onKeyGestureEvent(backGestureEvent)
+            listenerCaptor.value.onKeyGestureEvent(allAppsKeyGestureEvent)
 
             val model by
-                collectLastValue(kosmos.contextualEducationRepository.readGestureEduModelFlow(BACK))
+                collectLastValue(
+                    kosmos.contextualEducationRepository.readGestureEduModelFlow(ALL_APPS)
+                )
             assertThat(model?.lastShortcutTriggeredTime).isEqualTo(eduClock.instant())
         }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModelTest.kt
index 86b3f33..0a0ded7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModelTest.kt
@@ -34,6 +34,7 @@
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -85,26 +86,22 @@
         testScope.runTest {
             fingerprintPropertyRepository.supportsUdfps()
             biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
+
             val values by collectValues(underTest.deviceEntryParentViewAlpha)
+            runCurrent()
 
             keyguardTransitionRepository.sendTransitionSteps(
-                listOf(
-                    step(0f, TransitionState.STARTED),
-                    step(0f),
-                    step(0.1f),
-                    step(0.2f),
-                    step(0.3f),
-                    step(1f),
-                ),
+                from = KeyguardState.LOCKSCREEN,
+                to = KeyguardState.DOZING,
                 testScope,
             )
 
-            values.forEach { assertThat(it).isEqualTo(0f) }
+            assertThat(values[0]).isEqualTo(1f)
+            assertThat(values[1]).isEqualTo(0f)
         }
 
-
     @Test
-    fun lockscreenAlphaFadesOutAndFinishesVisible() =
+    fun lockscreenAlphaDoesNotFadeOut() =
         testScope.runTest {
             val alpha by collectValues(underTest.lockscreenAlpha)
             keyguardTransitionRepository.sendTransitionSteps(
@@ -113,31 +110,7 @@
                 testScope,
             )
 
-            assertThat(alpha[0]).isEqualTo(1f)
-            // Halfway through, it will have faded out
-            assertThat(alpha[1]).isEqualTo(0f)
-            // FINISHED alpha should be visible, to support pulsing
-            assertThat(alpha[2]).isEqualTo(1f)
-        }
-
-    @Test
-    fun deviceEntryBackgroundViewDisappear() =
-        testScope.runTest {
-            val values by collectValues(underTest.deviceEntryBackgroundViewAlpha)
-
-            keyguardTransitionRepository.sendTransitionSteps(
-                listOf(
-                    step(0f, TransitionState.STARTED),
-                    step(0f),
-                    step(0.1f),
-                    step(0.2f),
-                    step(0.3f),
-                    step(1f),
-                ),
-                testScope,
-            )
-
-            values.forEach { assertThat(it).isEqualTo(0f) }
+            alpha.forEach { assertThat(it).isEqualTo(1f) }
         }
 
     private fun step(value: Float, state: TransitionState = RUNNING): TransitionStep {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
similarity index 91%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneActionsViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
index c66ebf3..4253c29 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
@@ -63,7 +63,7 @@
 @RunWith(ParameterizedAndroidJunit4::class)
 @RunWithLooper
 @EnableSceneContainer
-class LockscreenSceneActionsViewModelTest : SysuiTestCase() {
+class LockscreenUserActionsViewModelTest : SysuiTestCase() {
 
     companion object {
         private const val parameterCount = 6
@@ -170,7 +170,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_COMMUNAL_HUB)
-    fun destinationScenes() =
+    fun userActions() =
         testScope.runTest {
             underTest.activateIn(this)
             kosmos.fakeDeviceEntryRepository.setLockscreenEnabled(true)
@@ -193,9 +193,9 @@
                     },
             )
 
-            val destinationScenes by collectLastValue(underTest.actions)
+            val userActions by collectLastValue(underTest.actions)
             val downDestination =
-                destinationScenes?.get(
+                userActions?.get(
                     Swipe(
                         SwipeDirection.Down,
                         fromSource = Edge.Top.takeIf { downFromEdge },
@@ -227,11 +227,10 @@
 
             val upScene by
                 collectLastValue(
-                    (destinationScenes?.get(Swipe(SwipeDirection.Up))
-                            as? UserActionResult.ChangeScene)
-                        ?.toScene
-                        ?.let { scene -> kosmos.sceneInteractor.resolveSceneFamily(scene) }
-                        ?: flowOf(null)
+                    (userActions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene?.let {
+                        scene ->
+                        kosmos.sceneInteractor.resolveSceneFamily(scene)
+                    } ?: flowOf(null)
                 )
 
             assertThat(upScene)
@@ -244,11 +243,10 @@
 
             val leftScene by
                 collectLastValue(
-                    (destinationScenes?.get(Swipe(SwipeDirection.Left))
-                            as? UserActionResult.ChangeScene)
-                        ?.toScene
-                        ?.let { scene -> kosmos.sceneInteractor.resolveSceneFamily(scene) }
-                        ?: flowOf(null)
+                    (userActions?.get(Swipe.Left) as? UserActionResult.ChangeScene)?.toScene?.let {
+                        scene ->
+                        kosmos.sceneInteractor.resolveSceneFamily(scene)
+                    } ?: flowOf(null)
                 )
 
             assertThat(leftScene)
@@ -260,8 +258,8 @@
                 )
         }
 
-    private fun createLockscreenSceneViewModel(): LockscreenSceneActionsViewModel {
-        return LockscreenSceneActionsViewModel(
+    private fun createLockscreenSceneViewModel(): LockscreenUserActionsViewModel {
+        return LockscreenUserActionsViewModel(
             deviceEntryInteractor = kosmos.deviceEntryInteractor,
             communalInteractor = kosmos.communalInteractor,
             shadeInteractor = kosmos.shadeInteractor,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataLoaderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataLoaderTest.kt
index 22e5896..c1dcf37 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataLoaderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataLoaderTest.kt
@@ -34,7 +34,6 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.Flags.MEDIA_RESUME_PROGRESS
-import com.android.systemui.flags.Flags.MEDIA_SESSION_ACTIONS
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.graphics.imageLoader
 import com.android.systemui.kosmos.testDispatcher
@@ -96,7 +95,6 @@
 
     @Before
     fun setUp() {
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         mediaControllerFactory.setControllerForToken(session.sessionToken, mediaController)
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeUserActionsViewModelTest.kt
similarity index 97%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneActionsViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeUserActionsViewModelTest.kt
index ed7f96fb..46b02e92 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeUserActionsViewModelTest.kt
@@ -37,7 +37,7 @@
 import com.android.systemui.scene.domain.resolver.homeSceneFamilyResolver
 import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
-import com.android.systemui.shade.ui.viewmodel.notificationsShadeSceneActionsViewModel
+import com.android.systemui.shade.ui.viewmodel.notificationsShadeUserActionsViewModel
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -52,14 +52,14 @@
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 @EnableSceneContainer
-class NotificationsShadeSceneActionsViewModelTest : SysuiTestCase() {
+class NotificationsShadeUserActionsViewModelTest : SysuiTestCase() {
 
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val sceneInteractor by lazy { kosmos.sceneInteractor }
     private val deviceUnlockedInteractor by lazy { kosmos.deviceUnlockedInteractor }
 
-    private val underTest by lazy { kosmos.notificationsShadeSceneActionsViewModel }
+    private val underTest by lazy { kosmos.notificationsShadeUserActionsViewModel }
 
     @Test
     fun upTransitionSceneKey_deviceLocked_lockscreen() =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeUserActionsViewModelTest.kt
similarity index 97%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneActionsViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeUserActionsViewModelTest.kt
index ba527d7..32772d2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeUserActionsViewModelTest.kt
@@ -53,14 +53,14 @@
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 @EnableSceneContainer
-class QuickSettingsShadeSceneActionsViewModelTest : SysuiTestCase() {
+class QuickSettingsShadeUserActionsViewModelTest : SysuiTestCase() {
 
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val sceneInteractor = kosmos.sceneInteractor
     private val deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor
 
-    private val underTest by lazy { kosmos.quickSettingsShadeSceneActionsViewModel }
+    private val underTest by lazy { kosmos.quickSettingsShadeUserActionsViewModel }
 
     @Test
     fun upTransitionSceneKey_deviceLocked_lockscreen() =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsUserActionsViewModelTest.kt
similarity index 98%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneActionsViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsUserActionsViewModelTest.kt
index f26a9db..6986cf8e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsUserActionsViewModelTest.kt
@@ -57,7 +57,7 @@
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper
 @EnableSceneContainer
-class QuickSettingsSceneActionsViewModelTest : SysuiTestCase() {
+class QuickSettingsUserActionsViewModelTest : SysuiTestCase() {
 
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
@@ -67,7 +67,7 @@
     private val sceneBackInteractor = kosmos.sceneBackInteractor
     private val sceneContainerStartable = kosmos.sceneContainerStartable
 
-    private lateinit var underTest: QuickSettingsSceneActionsViewModel
+    private lateinit var underTest: QuickSettingsUserActionsViewModel
 
     @Before
     fun setUp() {
@@ -75,7 +75,7 @@
 
         sceneContainerStartable.start()
         underTest =
-            QuickSettingsSceneActionsViewModel(
+            QuickSettingsUserActionsViewModel(
                 qsSceneAdapter = qsFlexiglassAdapter,
                 sceneBackInteractor = sceneBackInteractor,
             )
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index f365afb..4f7c013 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -49,7 +49,7 @@
 import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.flags.Flags
 import com.android.systemui.flags.fakeFeatureFlagsClassic
-import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneActionsViewModel
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenUserActionsViewModel
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.lifecycle.activateIn
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
@@ -65,10 +65,10 @@
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
 import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
 import com.android.systemui.shade.domain.interactor.shadeInteractor
-import com.android.systemui.shade.ui.viewmodel.ShadeSceneActionsViewModel
 import com.android.systemui.shade.ui.viewmodel.ShadeSceneContentViewModel
-import com.android.systemui.shade.ui.viewmodel.shadeSceneActionsViewModel
+import com.android.systemui.shade.ui.viewmodel.ShadeUserActionsViewModel
 import com.android.systemui.shade.ui.viewmodel.shadeSceneContentViewModel
+import com.android.systemui.shade.ui.viewmodel.shadeUserActionsViewModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
 import com.android.systemui.telephony.data.repository.fakeTelephonyRepository
@@ -145,8 +145,8 @@
     private lateinit var bouncerActionButtonInteractor: BouncerActionButtonInteractor
     private lateinit var bouncerSceneContentViewModel: BouncerSceneContentViewModel
 
-    private val lockscreenSceneActionsViewModel by lazy {
-        LockscreenSceneActionsViewModel(
+    private val mLockscreenUserActionsViewModel by lazy {
+        LockscreenUserActionsViewModel(
             deviceEntryInteractor = deviceEntryInteractor,
             communalInteractor = communalInteractor,
             shadeInteractor = kosmos.shadeInteractor,
@@ -154,7 +154,7 @@
     }
 
     private lateinit var shadeSceneContentViewModel: ShadeSceneContentViewModel
-    private lateinit var shadeSceneActionsViewModel: ShadeSceneActionsViewModel
+    private lateinit var mShadeUserActionsViewModel: ShadeUserActionsViewModel
 
     private val powerInteractor by lazy { kosmos.powerInteractor }
 
@@ -191,14 +191,14 @@
         bouncerSceneContentViewModel = kosmos.bouncerSceneContentViewModel
 
         shadeSceneContentViewModel = kosmos.shadeSceneContentViewModel
-        shadeSceneActionsViewModel = kosmos.shadeSceneActionsViewModel
+        mShadeUserActionsViewModel = kosmos.shadeUserActionsViewModel
 
         val startable = kosmos.sceneContainerStartable
         startable.start()
 
-        lockscreenSceneActionsViewModel.activateIn(testScope)
+        mLockscreenUserActionsViewModel.activateIn(testScope)
         shadeSceneContentViewModel.activateIn(testScope)
-        shadeSceneActionsViewModel.activateIn(testScope)
+        mShadeUserActionsViewModel.activateIn(testScope)
         bouncerSceneContentViewModel.activateIn(testScope)
         sceneContainerViewModel.activateIn(testScope)
 
@@ -229,7 +229,7 @@
     @Test
     fun swipeUpOnLockscreen_enterCorrectPin_unlocksDevice() =
         testScope.runTest {
-            val actions by collectLastValue(lockscreenSceneActionsViewModel.actions)
+            val actions by collectLastValue(mLockscreenUserActionsViewModel.actions)
             val upDestinationSceneKey =
                 (actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene
             assertThat(upDestinationSceneKey).isEqualTo(Scenes.Bouncer)
@@ -250,7 +250,7 @@
         testScope.runTest {
             setAuthMethod(AuthenticationMethodModel.None, enableLockscreen = true)
 
-            val actions by collectLastValue(lockscreenSceneActionsViewModel.actions)
+            val actions by collectLastValue(mLockscreenUserActionsViewModel.actions)
             val upDestinationSceneKey =
                 (actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene
             assertThat(upDestinationSceneKey).isEqualTo(Scenes.Gone)
@@ -262,7 +262,7 @@
     @Test
     fun swipeUpOnShadeScene_withAuthMethodSwipe_lockscreenNotDismissed_goesToLockscreen() =
         testScope.runTest {
-            val actions by collectLastValue(shadeSceneActionsViewModel.actions)
+            val actions by collectLastValue(mShadeUserActionsViewModel.actions)
             val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
             setAuthMethod(AuthenticationMethodModel.None, enableLockscreen = true)
             assertCurrentScene(Scenes.Lockscreen)
@@ -283,7 +283,7 @@
     @Test
     fun swipeUpOnShadeScene_withAuthMethodSwipe_lockscreenDismissed_goesToGone() =
         testScope.runTest {
-            val actions by collectLastValue(shadeSceneActionsViewModel.actions)
+            val actions by collectLastValue(mShadeUserActionsViewModel.actions)
             val canSwipeToEnter by collectLastValue(deviceEntryInteractor.canSwipeToEnter)
             val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
 
@@ -369,7 +369,7 @@
     fun swipeUpOnLockscreenWhileUnlocked_dismissesLockscreen() =
         testScope.runTest {
             unlockDevice()
-            val actions by collectLastValue(lockscreenSceneActionsViewModel.actions)
+            val actions by collectLastValue(mLockscreenUserActionsViewModel.actions)
             val upDestinationSceneKey =
                 (actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene
             assertThat(upDestinationSceneKey).isEqualTo(Scenes.Gone)
@@ -392,7 +392,7 @@
     fun dismissingIme_whileOnPasswordBouncer_navigatesToLockscreen() =
         testScope.runTest {
             setAuthMethod(AuthenticationMethodModel.Password)
-            val actions by collectLastValue(lockscreenSceneActionsViewModel.actions)
+            val actions by collectLastValue(mLockscreenUserActionsViewModel.actions)
             val upDestinationSceneKey =
                 (actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene
             assertThat(upDestinationSceneKey).isEqualTo(Scenes.Bouncer)
@@ -411,7 +411,7 @@
     fun bouncerActionButtonClick_opensEmergencyServicesDialer() =
         testScope.runTest {
             setAuthMethod(AuthenticationMethodModel.Password)
-            val actions by collectLastValue(lockscreenSceneActionsViewModel.actions)
+            val actions by collectLastValue(mLockscreenUserActionsViewModel.actions)
             val upDestinationSceneKey =
                 (actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene
             assertThat(upDestinationSceneKey).isEqualTo(Scenes.Bouncer)
@@ -432,7 +432,7 @@
         testScope.runTest {
             setAuthMethod(AuthenticationMethodModel.Password)
             startPhoneCall()
-            val actions by collectLastValue(lockscreenSceneActionsViewModel.actions)
+            val actions by collectLastValue(mLockscreenUserActionsViewModel.actions)
             val upDestinationSceneKey =
                 (actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene
             assertThat(upDestinationSceneKey).isEqualTo(Scenes.Bouncer)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneSceneActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModelTest.kt
similarity index 83%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneSceneActionsViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModelTest.kt
index b526275..03106ec 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneSceneActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModelTest.kt
@@ -43,17 +43,17 @@
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 @EnableSceneContainer
-class GoneSceneActionsViewModelTest : SysuiTestCase() {
+class GoneUserActionsViewModelTest : SysuiTestCase() {
 
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val shadeRepository by lazy { kosmos.shadeRepository }
-    private lateinit var underTest: GoneSceneActionsViewModel
+    private lateinit var underTest: GoneUserActionsViewModel
 
     @Before
     fun setUp() {
         underTest =
-            GoneSceneActionsViewModel(
+            GoneUserActionsViewModel(
                 shadeInteractor = kosmos.shadeInteractor,
             )
         underTest.activateIn(testScope)
@@ -62,21 +62,21 @@
     @Test
     fun downTransitionKey_splitShadeEnabled_isGoneToSplitShade() =
         testScope.runTest {
-            val destinationScenes by collectLastValue(underTest.actions)
+            val userActions by collectLastValue(underTest.actions)
             shadeRepository.setShadeLayoutWide(true)
             runCurrent()
 
-            assertThat(destinationScenes?.get(Swipe(SwipeDirection.Down))?.transitionKey)
+            assertThat(userActions?.get(Swipe(SwipeDirection.Down))?.transitionKey)
                 .isEqualTo(ToSplitShade)
         }
 
     @Test
     fun downTransitionKey_splitShadeDisabled_isNull() =
         testScope.runTest {
-            val destinationScenes by collectLastValue(underTest.actions)
+            val userActions by collectLastValue(underTest.actions)
             shadeRepository.setShadeLayoutWide(false)
             runCurrent()
 
-            assertThat(destinationScenes?.get(Swipe(SwipeDirection.Down))?.transitionKey).isNull()
+            assertThat(userActions?.get(Swipe(SwipeDirection.Down))?.transitionKey).isNull()
         }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/UserActionsViewModelTest.kt
similarity index 95%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneActionsViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/UserActionsViewModelTest.kt
index 900f2a4..972afb5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/UserActionsViewModelTest.kt
@@ -42,12 +42,12 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-class SceneActionsViewModelTest : SysuiTestCase() {
+class UserActionsViewModelTest : SysuiTestCase() {
 
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
 
-    private val underTest = FakeSceneActionsViewModel()
+    private val underTest = FakeUserActionsViewModel()
 
     @Test
     fun actions_emptyBeforeActivation() =
@@ -115,7 +115,7 @@
             assertThat(actions).isEmpty()
         }
 
-    private class FakeSceneActionsViewModel : SceneActionsViewModel() {
+    private class FakeUserActionsViewModel : UserActionsViewModel() {
 
         val upstream = MutableStateFlow<Map<UserAction, UserActionResult>>(emptyMap())
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelTest.kt
similarity index 98%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneActionsViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelTest.kt
index a931e65..9f3e126e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelTest.kt
@@ -64,7 +64,7 @@
 @TestableLooper.RunWithLooper
 @EnableSceneContainer
 @DisableFlags(DualShade.FLAG_NAME)
-class ShadeSceneActionsViewModelTest : SysuiTestCase() {
+class ShadeUserActionsViewModelTest : SysuiTestCase() {
 
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
@@ -72,7 +72,7 @@
     private val shadeRepository by lazy { kosmos.shadeRepository }
     private val qsSceneAdapter by lazy { kosmos.fakeQSSceneAdapter }
 
-    private val underTest: ShadeSceneActionsViewModel by lazy { kosmos.shadeSceneActionsViewModel }
+    private val underTest: ShadeUserActionsViewModel by lazy { kosmos.shadeUserActionsViewModel }
 
     @Before
     fun setUp() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
index 75ecb2c..beba162 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
@@ -133,7 +133,8 @@
                 mVisibilityLocationProvider,
                 mVisualStabilityProvider,
                 mWakefulnessLifecycle,
-                mKosmos.getCommunalInteractor(),
+                mKosmos.getCommunalSceneInteractor(),
+                mKosmos.getShadeInteractor(),
                 mKosmos.getKeyguardTransitionInteractor(),
                 mLogger);
         mCoordinator.attach(mNotifPipeline);
@@ -561,11 +562,12 @@
 
     @Test
     public void testCommunalShowingWillNotSuppressReordering() {
-        // GIVEN panel is expanded and communal is showing
+        // GIVEN panel is expanded, communal is showing, and QS is collapsed
         setPulsing(false);
         setFullyDozed(false);
         setSleepy(false);
         setPanelExpanded(true);
+        setQsExpanded(false);
         setCommunalShowing(true);
 
         // Reordering should be allowed
@@ -573,6 +575,20 @@
     }
 
     @Test
+    public void testQsExpandedOverCommunalWillSuppressReordering() {
+        // GIVEN panel is expanded and communal is showing, but QS is expanded
+        setPulsing(false);
+        setFullyDozed(false);
+        setSleepy(false);
+        setPanelExpanded(true);
+        setQsExpanded(true);
+        setCommunalShowing(true);
+
+        // Reordering should not be allowed
+        assertFalse(mNotifStabilityManager.isEntryReorderingAllowed(mEntry));
+    }
+
+    @Test
     public void testQueryingEntryReorderingButNotReportingReorderSuppressedDoesNotInvalidate() {
         // GIVEN visual stability is being maintained b/c panel is expanded
         setPulsing(false);
@@ -631,7 +647,12 @@
                         new ObservableTransitionState.Idle(
                                 isShowing ? CommunalScenes.Communal : CommunalScenes.Blank)
                 );
-        mKosmos.getCommunalRepository().setTransitionState(showingFlow);
+        mKosmos.getCommunalSceneInteractor().setTransitionState(showingFlow);
+        mTestScope.getTestScheduler().runCurrent();
+    }
+
+    private void setQsExpanded(boolean isExpanded) {
+        mKosmos.getShadeRepository().setQsExpansion(isExpanded ? 1.0f : 0.0f);
         mTestScope.getTestScheduler().runCurrent();
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
index a6fdd03..b5dbc3f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
@@ -22,8 +22,6 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.demomode.DemoMode
 import com.android.systemui.demomode.DemoModeController
-import com.android.systemui.flags.FakeFeatureFlagsClassic
-import com.android.systemui.flags.Flags
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.statusbar.connectivity.WifiPickerTrackerFactory
@@ -73,11 +71,6 @@
     private val demoModelFlow = MutableStateFlow<FakeWifiEventModel?>(null)
 
     private val mainExecutor = FakeExecutor(FakeSystemClock())
-    private val featureFlags =
-        FakeFeatureFlagsClassic().also {
-            it.set(Flags.INSTANT_TETHER, true)
-            it.set(Flags.WIFI_SECONDARY_NETWORKS, true)
-        }
 
     private val testDispatcher = UnconfinedTestDispatcher()
     private val testScope = TestScope(testDispatcher)
@@ -93,7 +86,6 @@
 
         realImpl =
             WifiRepositoryImpl(
-                featureFlags,
                 testScope.backgroundScope,
                 mainExecutor,
                 testDispatcher,
diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceConfigPlugin.kt b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceConfigPlugin.kt
index 509f022..84f39af 100644
--- a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceConfigPlugin.kt
+++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceConfigPlugin.kt
@@ -21,4 +21,6 @@
 interface BcSmartspaceConfigPlugin {
     /** Gets default date/weather disabled status. */
     val isDefaultDateWeatherDisabled: Boolean
+    /** Gets if Smartspace should use ViewPager2 */
+    val isViewPager2Enabled: Boolean
 }
diff --git a/packages/SystemUI/res/color/brightness_slider_track.xml b/packages/SystemUI/res/color/brightness_slider_track.xml
deleted file mode 100644
index 6028769..0000000
--- a/packages/SystemUI/res/color/brightness_slider_track.xml
+++ /dev/null
@@ -1,19 +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.
-  -->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@android:color/system_neutral2_500" android:lStar="40" />
-</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/arrow_pointing_down.xml b/packages/SystemUI/res/drawable/arrow_pointing_down.xml
index be39683..ca573c7 100644
--- a/packages/SystemUI/res/drawable/arrow_pointing_down.xml
+++ b/packages/SystemUI/res/drawable/arrow_pointing_down.xml
@@ -19,7 +19,7 @@
     android:height="24dp"
     android:viewportWidth="24.0"
     android:viewportHeight="24.0"
-    android:tint="?attr/colorControlNormal">
+    android:tint="?android:attr/textColorPrimary">
     <path
         android:fillColor="@android:color/white"
         android:pathData="M5.41,7.59L4,9l8,8 8,-8 -1.41,-1.41L12,14.17" />
diff --git a/packages/SystemUI/res/drawable/brightness_bar.xml b/packages/SystemUI/res/drawable/brightness_bar.xml
index 2afe164..3d1c1fb 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="@color/brightness_slider_track"/>
+    android:fillColor="?androidprv:attr/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 cae9d6b..ec15b10 100644
--- a/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
+++ b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
@@ -15,6 +15,7 @@
   ~ limitations under the License.
   -->
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
             android:paddingMode="stack" >
     <item android:id="@android:id/background"
         android:gravity="center_vertical|fill_horizontal">
@@ -24,7 +25,7 @@
             <shape>
                 <size android:height="@dimen/rounded_slider_track_width" />
                 <corners android:radius="@dimen/rounded_slider_track_corner_radius" />
-                <solid android:color="@color/brightness_slider_track" />
+                <solid android:color="?androidprv:attr/customColorShadeInactive" />
             </shape>
         </inset>
     </item>
diff --git a/packages/SystemUI/res/layout/alert_dialog_button_bar_systemui.xml b/packages/SystemUI/res/layout/alert_dialog_button_bar_systemui.xml
index e06bfdc..368fe82 100644
--- a/packages/SystemUI/res/layout/alert_dialog_button_bar_systemui.xml
+++ b/packages/SystemUI/res/layout/alert_dialog_button_bar_systemui.xml
@@ -52,7 +52,7 @@
         <Button
             android:id="@android:id/button1"
             style="?android:attr/buttonBarPositiveButtonStyle"
-            android:layout_marginStart="8dp"
+            android:layout_marginStart="@dimen/dialog_button_side_margin"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content" />
     </com.android.internal.widget.ButtonBarLayout>
diff --git a/packages/SystemUI/res/layout/ongoing_activity_chip.xml b/packages/SystemUI/res/layout/ongoing_activity_chip.xml
index 154397d..690a89a 100644
--- a/packages/SystemUI/res/layout/ongoing_activity_chip.xml
+++ b/packages/SystemUI/res/layout/ongoing_activity_chip.xml
@@ -17,7 +17,6 @@
      the chip. -->
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/ongoing_activity_chip"
     android:layout_width="wrap_content"
     android:layout_height="match_parent"
     android:layout_gravity="center_vertical|start"
diff --git a/packages/SystemUI/res/layout/screen_share_dialog.xml b/packages/SystemUI/res/layout/screen_share_dialog.xml
index aa083ad..0533c7e 100644
--- a/packages/SystemUI/res/layout/screen_share_dialog.xml
+++ b/packages/SystemUI/res/layout/screen_share_dialog.xml
@@ -64,30 +64,27 @@
             android:layout_height="wrap_content"
             android:text="@string/screenrecord_permission_dialog_warning_entire_screen"
             style="@style/TextAppearance.Dialog.Body.Message"
-            android:gravity="start"/>
+            android:gravity="start"
+            android:textAlignment="gravity"/>
 
         <!-- Buttons -->
         <com.android.internal.widget.ButtonBarLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:orientation="horizontal"
-            android:layout_marginTop="@dimen/screenrecord_buttons_margin_top">
+            android:layout_marginTop="@dimen/screenrecord_buttons_margin_top"
+            android:gravity="end">
             <Button
                 android:id="@android:id/button2"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_weight="0"
                 android:text="@string/cancel"
                 style="@style/Widget.Dialog.Button.BorderButton" />
-            <Space
-                android:layout_width="0dp"
-                android:layout_height="match_parent"
-                android:layout_weight="1"/>
             <Button
                 android:id="@android:id/button1"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_weight="0"
+                android:layout_marginStart="@dimen/dialog_button_side_margin"
                 android:text="@string/screenrecord_continue"
                 style="@style/Widget.Dialog.Button" />
         </com.android.internal.widget.ButtonBarLayout>
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index 4247c7e..ee75b31 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -99,7 +99,10 @@
                         android:gravity="center_vertical|start"
                     />
 
-                    <include layout="@layout/ongoing_activity_chip" />
+                    <include layout="@layout/ongoing_activity_chip"
+                        android:id="@+id/ongoing_activity_chip_primary"/>
+
+                    <!-- TODO(b/364653005): Add a second activity chip. -->
 
                     <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
                         android:id="@+id/notification_icon_area"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 7251f03..a1be54c 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Gebruik Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Gekoppel"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Oudiodeling"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gestoor"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ontkoppel"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiveer"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliet, goeie toestand"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliet, verbinding is beskikbaar"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satelliet-SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Noodoproepe of SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Werkprofiel"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Pret vir party mense, maar nie vir almal nie"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Stelsel-UI-ontvanger gee jou ekstra maniere om die Android-gebruikerkoppelvlak in te stel en te pasmaak. Hierdie eksperimentele kenmerke kan in toekomstige uitreikings verander, breek of verdwyn. Gaan versigtig voort."</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 54fb216d..23f3766 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"ብሉቱዝን ይጠቀሙ"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"ተገናኝቷል"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"የድምጽ ማጋራት"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ተቀምጧል"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ግንኙነትን አቋርጥ"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ያግብሩ"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ሳተላይት፣ ጥሩ ግንኙነት"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ሳተላይት፣ ግንኙነት አለ"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"ሳተላይት ኤስኦኤስ"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"የአደጋ ጥሪዎች ወይም ኤስኦኤስ"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"የስራ መገለጫ"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"ለአንዳንዶች አስደሳች ቢሆንም ለሁሉም አይደለም"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"የስርዓት በይነገጽ መቃኛ የAndroid ተጠቃሚ በይነገጹን የሚነካኩበት እና የሚያበጁበት ተጨማሪ መንገዶች ይሰጠዎታል። እነዚህ የሙከራ ባህሪዎች ወደፊት በሚኖሩ ልቀቶች ላይ ሊለወጡ፣ ሊሰበሩ ወይም ሊጠፉ ይችላሉ። ከጥንቃቄ ጋር ወደፊት ይቀጥሉ።"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 6866ed7..0ac0d03 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"استخدام البلوتوث"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"متّصل"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"مشاركة الصوت"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"محفوظ"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"إلغاء الربط"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"تفعيل"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"قمر صناعي، الاتصال جيد"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"قمر صناعي، الاتصال متوفّر"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"اتصالات الطوارئ بالقمر الصناعي"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"مكالمات الطوارئ أو ميزة \"اتصالات طوارئ بالقمر الصناعي\""</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"ملف العمل"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"متعة للبعض وليس للجميع"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"‏توفر لك أداة ضبط واجهة مستخدم النظام طرقًا إضافية لتعديل واجهة مستخدم Android وتخصيصها. ويمكن أن تطرأ تغييرات على هذه الميزات التجريبية أو يمكن أن تتعطل هذه الميزات أو تختفي في الإصدارات المستقبلية. عليك متابعة الاستخدام مع توخي الحذر."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 0c8ef43..a770c61 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"ব্লুটুথ ব্যৱহাৰ কৰক"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"সংযুক্ত আছে"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"অডিঅ’ শ্বেয়াৰ কৰা"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ছেভ কৰা হৈছে"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"সংযোগ বিচ্ছিন্ন কৰক"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"সক্ৰিয় কৰক"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"উপগ্ৰহ, ভাল সংযোগ"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"উপগ্ৰহ, সংযোগ উপলব্ধ"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"উপগ্ৰহ SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"জৰুৰীকালীন কল বা SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"কৰ্মস্থানৰ প্ৰ\'ফাইল"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"কিছুমানৰ বাবে আমোদজনক হয় কিন্তু সকলোৰে বাবে নহয়"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tunerএ আপোনাক Android ব্যৱহাৰকাৰী ইণ্টাৰফেইচ সলনি কৰিবলৈ আৰু নিজৰ উপযোগিতা অনুসৰি ব্যৱহাৰ কৰিবলৈ অতিৰিক্ত সুবিধা প্ৰদান কৰে। এই পৰীক্ষামূলক সুবিধাসমূহ সলনি হ\'ব পাৰে, সেইবোৰে কাম নকৰিব পাৰে বা আগন্তুক সংস্কৰণসমূহত সেইবোৰ অন্তৰ্ভুক্ত কৰা নহ’ব পাৰে। সাৱধানেৰে আগবাঢ়ক।"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index df3ecf7..cd7bbaf 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth-u açın"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Qoşulub"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Audio paylaşma"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Yadda saxlandı"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"əlaqəni kəsin"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivləşdirin"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Peyk, bağlantı yaxşıdır"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Peyk, bağlantı var"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Təcili peyk bağlantısı"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Təcili zənglər və ya SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"İş profili"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Hamı üçün deyil, bəziləri üçün əyləncəli"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner Android istifadəçi interfeysini dəyişdirmək və fərdiləşdirmək üçün Sizə ekstra yollar təklif edir."</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 9198710..25ecce5 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Koristi Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Povezano"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Deljenje zvuka"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Sačuvano"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekinite vezu"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivirajte"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, veza je dobra"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, veza je dostupna"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Hitna pomoć preko satelita"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Hitni pozivi ili hitna pomoć"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Poslovni profil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Zabava za neke, ali ne za sve"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Tjuner za korisnički interfejs sistema vam pruža dodatne načine za podešavanje i prilagođavanje Android korisničkog interfejsa. Ove eksperimentalne funkcije mogu da se promene, otkažu ili nestanu u budućim izdanjima. Budite oprezni."</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index c5c2912..5ea0621 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Выкарыстоўваць Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Падключана"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Абагульванне аўдыя"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Захавана"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"адключыць"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"актываваць"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Спадарожнікавая сувязь, добрае падключэнне"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Спадарожнікавая сувязь, падключэнне даступнае"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Экстраннае спадарожнікавае падключэнне"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Экстранныя выклікі або экстраннае спадарожнікавае падключэнне"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Працоўны профіль"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Цікава для некаторых, але не для ўсіх"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Наладка сістэмнага інтэрфейсу карыстальніка дае вам дадатковыя спосабы наладжвання і дапасоўвання карыстальніцкага інтэрфейсу Android. Гэтыя эксперыментальныя функцыі могуць змяніцца, перастаць працаваць або знікнуць у будучых версіях. Карыстайцеся з асцярожнасцю."</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 58f492e..ee11863 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Използване на Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Установена е връзка"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Споделяне на звука"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Запазено"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"прекратяване на връзката"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активиране"</string>
@@ -390,7 +392,7 @@
     <string name="performance" msgid="6552785217174378320">"Ефективност"</string>
     <string name="user_interface" msgid="3712869377953950887">"Потребителски интерфейс"</string>
     <string name="thermal" msgid="6758074791325414831">"Температура"</string>
-    <string name="custom" msgid="3337456985275158299">"Персонализирано"</string>
+    <string name="custom" msgid="3337456985275158299">"Персонализиране"</string>
     <string name="custom_trace_settings_dialog_title" msgid="2608570500144830554">"Настройки за персонализираната следа"</string>
     <string name="restore_default" msgid="5259420807486239755">"Възстановяване на стандартната настройка"</string>
     <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Режим за работа с една ръка"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Сателит, добра връзка"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Сателит, налице е връзка"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS чрез сателит"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Спешни обаждания или SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Потребителски профил в Work"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Забавно – но не за всички"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Тунерът на системния потребителски интерфейс ви предоставя допълнителни възможности за прецизиране и персонализиране на практическата работа с Android. Тези експериментални функции може да се променят, повредят или да изчезнат в бъдещите версии. Действайте внимателно."</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index c9e24f0..2536cb7 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"ব্লুটুথ ব্যবহার করুন"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"কানেক্ট করা আছে"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"অডিও শেয়ারিং"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"সেভ করা আছে"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ডিসকানেক্ট করুন"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"চালু করুন"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"স্যাটেলাইট, ভালো কানেকশন"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"স্যাটেলাইট, কানেকশন উপলভ্য আছে"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"স্যাটেলাইট SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"জরুরি কল বা SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"কাজের প্রোফাইল"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"কিছু ব্যক্তির জন্য মজাদার কিন্তু সকলের জন্য নয়"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"এই পরীক্ষামূলক বৈশিষ্ট্যগুলি ভবিষ্যতের সংস্করণগুলির মধ্যে পরিবর্তিত, বিভাজিত এবং অদৃশ্য হয়ে যেতে পারে৷ সাবধানতার সাথে এগিয়ে যান৷ সিস্টেম UI টিউনার আপনাকে Android ব্যবহারকারী ইন্টারফেসের সূক্ষ্ম সমন্বয় এবং কাস্টমাইজ করার অতিরিক্ত উপায়গুলি প্রদান করে৷"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 8949567..43ae5c7 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Koristi Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Povezano"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Dijeljenje zvuka"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Sačuvano"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekid veze"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiviranje"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobra veza"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, veza je dostupna"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Hitna pomoć putem satelita"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Hitni pozivi ili pomoć"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Radni profil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Zabava za neke, ali ne za sve"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Podešavač za korisnički interfejs sistema vam omogućava dodatne načine da podesite i prilagodite Androidov interfejs. Ove eksperimentalne funkcije se u budućim verzijama mogu mijenjati, kvariti ili nestati. Budite oprezni."</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 74cce98..187e75e 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -110,7 +110,7 @@
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Vols gravar la pantalla?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Grava una aplicació"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Grava tota la pantalla"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quan graves tota la pantalla, es grava tot el que es mostra en pantalla. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos, i l\'àudio i el vídeo."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quan graves tota la pantalla, es grava tot el que es mostra en pantalla. Per aquest motiu, ves amb compte amb elements com les contrasenyes, les dades de pagament, els missatges, les fotos, i l\'àudio i el vídeo."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Quan graves una aplicació, es grava tot el que es mostra o es reprodueix en aquesta aplicació. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos, i l\'àudio i el vídeo."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grava la pantalla"</string>
     <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Tria una aplicació per gravar"</string>
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Utilitza el Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Connectat"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Compartició d\'àudio"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Desat"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconnecta"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activa"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satèl·lit, bona connexió"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satèl·lit, connexió disponible"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS per satèl·lit"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Trucades d\'emergència o SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de treball"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diversió per a uns quants, però no per a tothom"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"El Personalitzador d\'interfície d\'usuari presenta opcions addicionals per canviar i personalitzar la interfície d\'usuari d\'Android. És possible que aquestes funcions experimentals canviïn, deixin de funcionar o desapareguin en versions futures. Continua amb precaució."</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 8c0571e..13e0377 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Používat Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Připojeno"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Sdílení zvuku"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Uloženo"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"odpojit"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivovat"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobré připojení"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, připojení je k dispozici"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS přes satelit"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Tísňová volání nebo SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Pracovní profil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Zábava, která není pro každého"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Nástroj na ladění uživatelského rozhraní systému vám nabízí další způsoby, jak si vyladit a přizpůsobit uživatelské rozhraní Android. Tyto experimentální funkce mohou v dalších verzích chybět, nefungovat nebo být změněny. Postupujte proto prosím opatrně."</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 9b72478..4ba9fe9 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Brug Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Der er oprettet forbindelse"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Lyddeling"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gemt"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"afbryd forbindelse"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivér"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellit – god forbindelse"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellit – forbindelsen er tilgængelig"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS-meldinger via satellit"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Nødopkald eller SOS-meldinger via satellit"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Arbejdsprofil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Sjovt for nogle, men ikke for alle"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner giver dig flere muligheder for at justere og tilpasse Android-brugerfladen. Disse eksperimentelle funktioner kan ændres, gå i stykker eller forsvinde i fremtidige udgivelser. Vær forsigtig, hvis du fortsætter."</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 7bfdf67..7a8d06c 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth verwenden"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Verbunden"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Audiofreigabe"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gespeichert"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"Verknüpfung aufheben"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivieren"</string>
@@ -629,7 +631,7 @@
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Einstellungen"</string>
     <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Automatische Untertitel"</string>
     <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Auf verträglichere Lautstärke eingestellt"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Die Kopfhörerlautstärke war länger als empfohlen hoch eingestellt"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Die Kopfhörer sind schon länger als empfohlen auf hohe Lautstärke eingestellt"</string>
     <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Die Kopfhörerlautstärke hat für diese Woche das Sicherheitslimit überschritten"</string>
     <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Weiterhören"</string>
     <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Leiser stellen"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellit, Verbindung gut"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellit, Verbindung verfügbar"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Notruf über Satellit"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Notrufe oder SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Arbeitsprofil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Für einige ein Vergnügen, aber nicht für alle"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Mit System UI Tuner erhältst du zusätzliche Möglichkeiten, die Android-Benutzeroberfläche anzupassen. Achtung: Diese Testfunktionen können sich ändern, abstürzen oder in zukünftigen Versionen verschwinden."</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index ed17959..015d625 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Χρήση Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Συνδέθηκε"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Κοινή χρήση ήχου"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Αποθηκεύτηκε"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"αποσύνδεση"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ενεργοποίηση"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Δορυφορική, καλή σύνδεση"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Δορυφορική, διαθέσιμη σύνδεση"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Δορυφορικό SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Κλήσεις έκτακτης ανάγκης ή SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Προφίλ εργασίας"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Διασκέδαση για ορισμένους, αλλά όχι για όλους"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Το System UI Tuner σάς προσφέρει επιπλέον τρόπους για να τροποποιήσετε και να προσαρμόσετε τη διεπαφή χρήστη Android. Αυτές οι πειραματικές λειτουργίες ενδέχεται να τροποποιηθούν, να παρουσιάσουν σφάλματα ή να καταργηθούν σε μελλοντικές εκδόσεις. Συνεχίστε με προσοχή."</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 0565be8..bab9a50 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Use Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Connected"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Audio sharing"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Emergency calls or SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Work profile"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Fun for some but not for all"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customise the Android user interface. These experimental features may change, break or disappear in future releases. Proceed with caution."</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 17642f7..67ce124 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Use Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Connected"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Audio Sharing"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 0565be8..bab9a50 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Use Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Connected"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Audio sharing"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Emergency calls or SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Work profile"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Fun for some but not for all"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customise the Android user interface. These experimental features may change, break or disappear in future releases. Proceed with caution."</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 0565be8..bab9a50 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Use Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Connected"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Audio sharing"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Emergency calls or SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Work profile"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Fun for some but not for all"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customise the Android user interface. These experimental features may change, break or disappear in future releases. Proceed with caution."</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index d31d328..4317f86 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‎‎‎‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‎‎‎‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‏‏‏‏‎Use Bluetooth‎‏‎‎‏‎"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‎‎‎Connected‎‏‎‎‏‎"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‏‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‏‎‎Audio Sharing‎‏‎‎‏‎"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‏‎‎‏‏‎‏‏‎‏‏‏‎‎‎‏‏‎‎‎‏‏‏‎‏‏‎‎‏‎‏‎Saved‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‎‎disconnect‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‎‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‏‎activate‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 53c38e2..b9cfbaa 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -110,7 +110,7 @@
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"¿Quieres grabar la pantalla?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Grabar una app"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Grabar toda la pantalla"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Cuando grabes toda la pantalla, se registrará todo lo que se muestre en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Cuando grabes toda la pantalla, se grabará todo lo que se muestre en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Cuando grabes una app, se registrará todo lo que se muestre o reproduzca en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grabar pantalla"</string>
     <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Elige una app para grabar"</string>
@@ -300,6 +300,8 @@
     <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">"Uso compartido de audio"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <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>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, buena conexión"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexión disponible"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS por satélite"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Llamadas de emergencia o SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabajo"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diversión solo para algunas personas"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"El sintonizador de IU del sistema te brinda más formas para editar y personalizar la interfaz de usuario de Android. Estas funciones experimentales pueden cambiar, dejar de funcionar o no incluirse en futuras versiones. Procede con precaución."</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 0bebccf..b392959 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -300,6 +300,8 @@
     <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>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <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>
@@ -390,7 +392,7 @@
     <string name="performance" msgid="6552785217174378320">"Rendimiento"</string>
     <string name="user_interface" msgid="3712869377953950887">"Interfaz de usuario"</string>
     <string name="thermal" msgid="6758074791325414831">"Temperatura"</string>
-    <string name="custom" msgid="3337456985275158299">"Otro"</string>
+    <string name="custom" msgid="3337456985275158299">"Config. personalizada"</string>
     <string name="custom_trace_settings_dialog_title" msgid="2608570500144830554">"Ajustes de traza personalizados"</string>
     <string name="restore_default" msgid="5259420807486239755">"Restaurar ajustes predeterminados"</string>
     <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Modo Una mano"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, buena conexión"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexión disponible"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS por satélite"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Llamadas de emergencia o SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabajo"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diversión solo para algunos"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"El configurador de UI del sistema te ofrece otras formas de modificar y personalizar la interfaz de usuario de Android. Estas funciones experimentales pueden cambiar, fallar o desaparecer en futuras versiones. Te recomendamos que tengas cuidado."</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index b2ffa80..c56d101 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Kasuta Bluetoothi"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Ühendatud"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Heli jagamine"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvestatud"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"katkesta ühendus"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiveeri"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliit, hea ühendus"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliit, ühendus on saadaval"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satelliit-SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Hädaabikõned või SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Tööprofiil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Kõik ei pruugi sellest rõõmu tunda"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Süsteemi kasutajaliidese tuuner pakub täiendavaid võimalusi Androidi kasutajaliidese muutmiseks ja kohandamiseks. Need katselised funktsioonid võivad muutuda, rikki minna või tulevastest versioonidest kaduda. Olge jätkamisel ettevaatlik."</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index d8cff19..ccebe2b 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Erabili Bluetootha"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Konektatuta"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Audioa partekatzea"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gordeta"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"deskonektatu"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktibatu"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelitea, konexio ona"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelitea, konexioa erabilgarri"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satelite bidezko SOS komunikazioa"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Larrialdi-deiak edo SOS komunikazioa"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Laneko profila"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Dibertsioa batzuentzat, baina ez guztientzat"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Sistemaren erabiltzaile-interfazearen konfiguratzaileak Android erabiltzaile-interfazea moldatzeko eta pertsonalizatzeko modu gehiago eskaintzen dizkizu. Baliteke eginbide esperimental horiek hurrengo kaleratzeetan aldatuta, etenda edo desagertuta egotea. Kontuz erabili."</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 5b17c44..7e622cf 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"استفاده از بلوتوث"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"متصل"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"اشتراک صدا"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ذخیره‌شده"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"قطع اتصال"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"فعال کردن"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ماهواره، اتصال خوب است"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ماهواره، اتصال دردسترس است"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"درخواست کمک ماهواره‌ای"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"تماس اضطراری یا درخواست کمک اضطراری"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"نمایه کاری"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"برای بعضی افراد سرگرم‌کننده است اما نه برای همه"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"‏«تنظیم‌کننده واسط کاربری سیستم» روش‌های بیشتری برای تنظیم دقیق و سفارشی کردن واسط کاربری Android در اختیار شما قرار می‌دهد. ممکن است این ویژگی‌های آزمایشی تغییر کنند، خراب شوند یا در نسخه‌های آینده جود نداشته باشند. با احتیاط ادامه دهید."</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 9244bec..4d7f41a3 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Käytä Bluetoothia"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Yhdistetty"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Audionjako"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Tallennettu"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"katkaise yhteys"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivoi"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliitti, hyvä yhteys"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliitti, yhteys saatavilla"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Hätäpuhelut tai Satellite SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Työprofiili"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Ei sovellu kaikkien käyttöön"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner antaa lisämahdollisuuksia Android-käyttöliittymän muokkaamiseen. Nämä kokeelliset ominaisuudet voivat muuttua, lakata toimimasta tai kadota milloin tahansa. Jatka omalla vastuullasi."</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 41305af..51dc60f 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Utiliser le Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Connecté"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Partage audio"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Enregistré"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"Déconnecter"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"Activer"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Bonne connexion satellite"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Connexion satellite accessible"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS par satellite"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Appels d\'urgence ou SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil professionnel"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Divertissant pour certains, mais pas pour tous"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner vous propose de nouvelles manières d\'adapter et de personnaliser l\'interface utilisateur d\'Android. Ces fonctionnalités expérimentales peuvent être modifiées, cesser de fonctionner ou disparaître dans les versions futures. À utiliser avec prudence."</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 4df98cf..bd6c664 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -110,7 +110,7 @@
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Enregistrer l\'écran ?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Enregistrer une appli"</string>
     <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Enregistrer tout l\'écran"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Lorsque vous enregistrez tout votre écran, tout ce qui s\'affiche sur celui-ci est enregistré. Faites donc attention aux éléments tels que les mots de passe, détails de mode de paiement, messages, photos et contenus audio et vidéo."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Lorsque vous enregistrez l\'intégralité de votre écran, tout ce qui s\'y affiche est enregistré. Faites donc attention aux éléments tels que les mots de passe, les détails du mode de paiement, les messages, les photos, et les contenus audio et vidéo."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Lorsque vous enregistrez une appli, tout ce qui est affiché ou lu dans celle-ci est enregistré. Faites donc attention aux éléments tels que les mots de passe, détails de mode de paiement, messages, photos et contenus audio et vidéo."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Enregistrer l\'écran"</string>
     <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Choisir l\'appli à enregistrer"</string>
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Utiliser le Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Connecté"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Partage audio"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Enregistré"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"dissocier"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activer"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Bonne connexion satellite"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Connexion satellite disponible"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS par satellite"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Appels d\'urgence ou SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil professionnel"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Divertissant pour certains, mais pas pour tous"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner vous propose de nouvelles manières d\'adapter et de personnaliser l\'interface utilisateur Android. Ces fonctionnalités expérimentales peuvent être modifiées, cesser de fonctionner ou disparaître dans les versions futures. À utiliser avec prudence."</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 1fe1242..81e96d6 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Usar Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Estableceuse a conexión"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Audio compartido"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gardouse"</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>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, boa conexión"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexión dispoñible"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS por satélite"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Chamadas de emerxencia ou SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de traballo"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diversión só para algúns"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"O configurador da IU do sistema ofréceche formas adicionais de modificar e personalizar a interface de usuario de Android. Estas funcións experimentais poden cambiar, interromperse ou desaparecer en futuras versións. Continúa con precaución."</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 7ecc057..ffa8554 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"બ્લૂટૂથનો ઉપયોગ કરો"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"કનેક્ટેડ છે"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"ઑડિયો શેરિંગ"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"સાચવેલું"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ડિસ્કનેક્ટ કરો"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"સક્રિય કરો"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"સૅટલાઇટ, સારું કનેક્શન"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"સૅટલાઇટ, કનેક્શન ઉપલબ્ધ છે"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"ઇમર્જન્સી સૅટલાઇટ સહાય"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"ઇમર્જન્સી કૉલ અથવા SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"ઑફિસની પ્રોફાઇલ"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"કેટલાક માટે મજા પરંતુ બધા માટે નહીં"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"સિસ્ટમ UI ટ્યૂનર તમને Android વપરાશકર્તા ઇન્ટરફેસને ટ્વીક અને કસ્ટમાઇઝ કરવાની વધારાની રીતો આપે છે. ભાવિ રીલિઝેસમાં આ પ્રાયોગિક સુવિધાઓ બદલાઈ, ભંગ અથવા અદૃશ્ય થઈ શકે છે. સાવધાની સાથે આગળ વધો."</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index c6a5e57..b56b30c 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -110,7 +110,7 @@
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"क्या आपको स्क्रीन रिकॉर्ड करनी है?"</string>
     <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_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>
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"ब्लूटूथ इस्तेमाल करें"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"कनेक्ट है"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"ऑडियो शेयर करने की सुविधा"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"सेव किया गया"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"डिसकनेक्ट करें"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"चालू करें"</string>
@@ -628,8 +630,8 @@
     <string name="sound_settings" msgid="8874581353127418308">"आवाज़ और वाइब्रेशन"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"सेटिंग"</string>
     <string name="volume_panel_captioning_title" msgid="5984936949147684357">"लाइव कैप्शन"</string>
-    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"आवाज़ को कम करके, सुरक्षित लेवल पर सेट कर दिया गया है"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"हेडफ़ोन की आवाज़ सुझाए गए समय से देर तक ज़्यादा रही"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"आवाज़ को कम करके, सुरक्षित लेवल पर सेट किया गया"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"हेडफ़ोन की आवाज़ सुझाए गए समय के बाद भी ज़्यादा रही"</string>
     <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"इस हफ़्ते के लिए हेडफ़ोन की आवाज़, सुझाई गई सीमा से ज़्यादा हो गई है"</string>
     <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"सुनना जारी रखें"</string>
     <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"आवाज़ कम करें"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"सैटलाइट कनेक्शन अच्छा है"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"सैटलाइट कनेक्शन उपलब्ध है"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"सैटलाइट एसओएस"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"आपातकालीन कॉल या एसओएस"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"वर्क प्रोफ़ाइल"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"कुछ के लिए मज़ेदार लेकिन सबके लिए नहीं"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"सिस्टम यूज़र इंटरफ़ेस (यूआई) ट्यूनर, आपको Android यूज़र इंटरफ़ेस में सुधार लाने और उसे अपनी पसंद के हिसाब से बदलने के कुछ और तरीके देता है. प्रयोग के तौर पर इस्तेमाल हो रहीं ये सुविधाएं आगे चल कर रिलीज़ की जा सकती हैं, रोकी जा सकती हैं या दिखाई देना बंद हो सकती हैं. सावधानी से आगे बढ़ें."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 2edf138..e1b2df2 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Koristi Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Povezano"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Zajedničko slušanje"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Spremljeno"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekini vezu"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiviraj"</string>
@@ -389,7 +391,7 @@
     <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Snimanje zaslona"</string>
     <string name="performance" msgid="6552785217174378320">"Izvedba"</string>
     <string name="user_interface" msgid="3712869377953950887">"Korisničko sučelje"</string>
-    <string name="thermal" msgid="6758074791325414831">"Termalno"</string>
+    <string name="thermal" msgid="6758074791325414831">"Pregrijavanje"</string>
     <string name="custom" msgid="3337456985275158299">"Prilagođeno"</string>
     <string name="custom_trace_settings_dialog_title" msgid="2608570500144830554">"Postavke prilagođenog praćenja"</string>
     <string name="restore_default" msgid="5259420807486239755">"Vrati na zadano"</string>
@@ -629,7 +631,7 @@
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Postavke"</string>
     <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Automatski titlovi"</string>
     <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Glasnoća je stišana na sigurniju razinu"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Glasnoća u slušalicama pojačana je dulje nego što se preporučuje"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Zvuk u slušalicama bio je preglasan dulje nego što se preporučuje"</string>
     <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Glasnoća slušalica premašila je sigurno ograničenje za ovaj tjedan"</string>
     <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Nastavi slušati"</string>
     <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Stišaj"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobra veza"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, veza je dostupna"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS putem satelita"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Hitni pozivi ili SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Poslovni profil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Zabava za neke, ali ne za sve"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Ugađanje korisničkog sučelja sustava pruža vam dodatne načine za prilagodbu korisničkog sučelja Androida. Te se eksperimentalne značajke mogu promijeniti, prekinuti ili nestati u budućim izdanjima. Nastavite uz oprez."</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 36bae57..f4d34fcc 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth használata"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Csatlakozva"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Hang megosztása"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Mentve"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"leválasztás"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiválás"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Műhold, jó kapcsolat"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Műhold, van rendelkezésre álló kapcsolat"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Műholdas SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Segélyhívás vagy SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Munkaprofil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Egyeseknek tetszik, másoknak nem"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"A Kezelőfelület-hangoló az Android felhasználói felületének szerkesztéséhez és testreszabásához nyújt további megoldásokat. Ezek a kísérleti funkciók változhatnak vagy megsérülhetnek a későbbi kiadásokban, illetve eltűnhetnek azokból. Körültekintően járjon el."</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 24e9065..3b7855b 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Միացնել Bluetooth-ը"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Միացված է"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Աուդիոյի փոխանցում"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Պահված է"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"անջատել"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ակտիվացնել"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Արբանյակային լավ կապ"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Հասանելի է արբանյակային կապ"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Շտապ կանչեր կամ SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Աշխատանքային պրոֆիլ"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Զվարճանք մեկ՝ որոշակի մարդու համար"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Համակարգի ՕՄ-ի կարգավորիչը հնարավորություն է տալիս հարմարեցնել Android-ի օգտատիրոջ միջերեսը: Այս փորձնական գործառույթները կարող են հետագա թողարկումների մեջ փոփոխվել, խափանվել կամ ընդհանրապես չհայտնվել: Եթե շարունակում եք, զգուշացեք:"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index d5f766b..3ddd9f11 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Gunakan Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Terhubung"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Berbagi Audio"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Disimpan"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"berhenti hubungkan"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktifkan"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, koneksi baik"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, koneksi tersedia"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS via Satelit"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Panggilan darurat atau SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil kerja"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Tidak semua orang menganggapnya baik"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Penyetel Antarmuka Pengguna Sistem memberikan cara tambahan untuk mengubah dan menyesuaikan antarmuka pengguna Android. Fitur eksperimental ini dapat berubah, rusak, atau menghilang dalam rilis di masa mendatang. Lanjutkan dengan hati-hati."</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index b3291bb..8c57ed1 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Nota Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Tengt"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Hljóði deilt"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Vistað"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"aftengja"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"virkja"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Gervihnöttur, góð tenging"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Gervihnöttur, tenging tiltæk"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Gervihnattar-SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Neyðarsímtöl eða SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Vinnusnið"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Þetta er ekki allra"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Fínstillingar kerfisviðmóts gera þér kleift að fínstilla og sérsníða notendaviðmót Android. Þessir tilraunaeiginleikar geta breyst, bilað eða horfið í síðari útgáfum. Gakktu því hægt um gleðinnar dyr."</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index b37eff9..559e529 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="4811759950673118541">"UI sistema"</string>
+    <string name="app_label" msgid="4811759950673118541">"UI di sistema"</string>
     <string name="battery_low_title" msgid="5319680173344341779">"Attivare il risparmio energetico?"</string>
     <string name="battery_low_description" msgid="3282977755476423966">"Batteria rimanente: <xliff:g id="PERCENTAGE">%s</xliff:g>. Il risparmio energetico attiva il tema scuro, limita l\'attività in background e ritarda le notifiche."</string>
     <string name="battery_low_intro" msgid="5148725009653088790">"Il risparmio energetico attiva il tema scuro, limita l\'attività in background e ritarda le notifiche."</string>
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Usa il Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Dispositivo connesso"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Condivisione audio"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Dispositivo salvato"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnetti"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"attiva"</string>
@@ -390,7 +392,7 @@
     <string name="performance" msgid="6552785217174378320">"Prestazioni"</string>
     <string name="user_interface" msgid="3712869377953950887">"Interfaccia utente"</string>
     <string name="thermal" msgid="6758074791325414831">"Termico"</string>
-    <string name="custom" msgid="3337456985275158299">"Personalizzate"</string>
+    <string name="custom" msgid="3337456985275158299">"Personalizzata"</string>
     <string name="custom_trace_settings_dialog_title" msgid="2608570500144830554">"Impostazioni di traccia personalizzate"</string>
     <string name="restore_default" msgid="5259420807486239755">"Ripristina predefinite"</string>
     <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Modalità a una mano"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellitare, connessione buona"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellitare, connessione disponibile"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS satellitare"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Chiamate di emergenza o SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profilo di lavoro"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Il divertimento riservato a pochi eletti"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"L\'Ottimizzatore UI di sistema mette a disposizione altri metodi per modificare e personalizzare l\'interfaccia utente di Android. Queste funzioni sperimentali potrebbero cambiare, interrompersi o scomparire nelle versioni successive. Procedi con cautela."</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index ecb8409..907f846 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"‏שימוש ב-Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"מחובר"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"שיתוף אודיו"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"נשמר"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ניתוק"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"הפעלה"</string>
@@ -381,7 +383,7 @@
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"התחלה"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"עצירה"</string>
     <string name="qs_record_issue_label" msgid="8166290137285529059">"תיעוד הבעיה"</string>
-    <string name="qs_record_issue_start" msgid="2979831312582567056">"התחלה"</string>
+    <string name="qs_record_issue_start" msgid="2979831312582567056">"קדימה"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"עצירה"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"דיווח על באג"</string>
     <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"איזה חלק בחוויית השימוש שלך במכשיר הושפע?"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 98d320d..54ba7b5 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth を使用"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"接続しました"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"音声の共有"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"保存済み"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"接続を解除"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"有効化"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"衛生、接続状態良好"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"衛生、接続利用可能"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"衛星 SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"緊急通報または SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"仕事用プロファイル"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"一部の方のみお楽しみいただける限定公開ツール"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"システムUI調整ツールでは、Androidユーザーインターフェースの調整やカスタマイズを行えます。これらの試験運用機能は今後のリリースで変更となったり、中止となったり、削除されたりする可能性がありますのでご注意ください。"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index d85d7c1..bc0fa35 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth-ის გამოყენება"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"დაკავშირებული"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"აუდიოს გაზიარება"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"შენახული"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"კავშირის გაწყვეტა"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"გააქტიურება"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"კარგი სატელიტური კავშირი"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ხელმისაწვდომია სატელიტური კავშირი"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"სატელიტური SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"გადაუდებელი ზარი ან SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"სამსახურის პროფილი"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"ზოგისთვის გასართობია, მაგრამ არა ყველასთვის"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"სისტემის UI ტუნერი გაძლევთ დამატებით გზებს Android-ის სამომხმარებლო ინტერფეისის პარამეტრების დაყენებისთვის. ეს ექსპერიმენტული მახასიათებლები შეიძლება შეიცვალოს, შეწყდეს ან გაქრეს მომავალ ვერსიებში. სიფრთხილით გააგრძელეთ."</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 7a43b4b..aa06784 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth-ты пайдалану"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Қосылды"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Аудио бөлісу"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Сақталды"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ажырату"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"іске қосу"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Жерсерік, байланыс жақсы."</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Жерсерік, байланыс бар."</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Құтқару қызметіне қоңырау шалу немесе SOS сигналын жіберу"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Жұмыс профилі"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Кейбіреулерге қызық, бірақ барлығына емес"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Жүйелік пайдаланушылық интерфейс тюнері Android пайдаланушылық интерфейсін реттеудің қосымша жолдарын береді. Бұл эксперименттік мүмкіндіктер болашақ шығарылымдарда өзгеруі, бұзылуы немесе жоғалуы мүмкін. Сақтықпен жалғастырыңыз."</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 2319623..fd64db5 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"ប្រើប៊្លូធូស"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"បានភ្ជាប់"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"ការស្ដាប់សំឡេងរួមគ្នា"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"បាន​រក្សាទុក"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ផ្ដាច់"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"បើកដំណើរការ"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ផ្កាយរណប មានការតភ្ជាប់ល្អ"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ផ្កាយរណប អាចតភ្ជាប់បាន"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"ការប្រកាសអាសន្នតាមផ្កាយរណប"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"ការហៅទៅលេខសង្គ្រោះបន្ទាន់ ឬ SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"កម្រងព័ត៌មានការងារ"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"ល្អសម្រាប់អ្នកប្រើមួយចំនួន តែមិនសម្រាប់គ្រប់គ្នាទេ"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"កម្មវិធីសម្រួល UI ប្រព័ន្ធផ្តល់ជូនអ្នកនូវមធ្យោបាយបន្ថែមទៀតដើម្បីកែសម្រួល និងប្តូរចំណុចប្រទាក់អ្នកប្រើ Android តាមបំណង។ លក្ខណៈពិសេសសាកល្បងនេះអាចនឹងផ្លាស់ប្តូរ បំបែក ឬបាត់បង់បន្ទាប់ពីការចេញផ្សាយនាពេលអនាគត។ សូមបន្តដោយប្រុងប្រយ័ត្ន។"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index aeb3b1ef0..94979b0 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"ಬ್ಲೂಟೂತ್ ಬಳಸಿ"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"ಆಡಿಯೋ ಹಂಚಿಕೊಳ್ಳುವಿಕೆ"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ಸೇವ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ಡಿಸ್‌ಕನೆಕ್ಟ್ ಮಾಡಿ"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ಸ್ಯಾಟಲೈಟ್‌, ಕನೆಕ್ಷನ್ ಉತ್ತಮವಾಗಿದೆ"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ಸ್ಯಾಟಲೈಟ್, ಕನೆಕ್ಷನ್ ಲಭ್ಯವಿದೆ"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"ಸ್ಯಾಟಲೈಟ್ SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"ತುರ್ತು ಕರೆಗಳು ಅಥವಾ SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"ಕೆಲಸದ ಪ್ರೊಫೈಲ್"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"ಕೆಲವರಿಗೆ ಮೋಜು ಆಗಿದೆ ಎಲ್ಲರಿಗೆ ಇಲ್ಲ"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"ಸಿಸ್ಟಂ UI ಟ್ಯೂನರ್ ನಿಮಗೆ Android ಬಳಕೆದಾರ ಅಂತರಸಂಪರ್ಕವನ್ನು ಸರಿಪಡಿಸಲು ಮತ್ತು ಕಸ್ಟಮೈಸ್ ಮಾಡಲು ಹೆಚ್ಚುವರಿ ಮಾರ್ಗಗಳನ್ನು ನೀಡುತ್ತದೆ. ಈ ಪ್ರಾಯೋಗಿಕ ವೈಶಿಷ್ಟ್ಯಗಳು ಭವಿಷ್ಯದ ಬಿಡುಗಡೆಗಳಲ್ಲಿ ಬದಲಾಗಬಹುದು, ವಿರಾಮವಾಗಬಹುದು ಅಥವಾ ಕಾಣಿಸಿಕೊಳ್ಳದಿರಬಹುದು. ಎಚ್ಚರಿಕೆಯಿಂದ ಮುಂದುವರಿಯಿರಿ."</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 277582c..e316ffd 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"블루투스 사용"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"연결됨"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"오디오 공유"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"저장됨"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"연결 해제"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"실행"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"위성, 연결 상태 양호"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"위성, 연결 가능"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"위성 긴급 SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"긴급 전화 또는 SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"직장 프로필"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"마음에 들지 않을 수도 있음"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"시스템 UI 튜너를 사용하면 Android 사용자 인터페이스를 변경 및 맞춤설정할 수 있습니다. 이러한 실험실 기능은 향후 출시 버전에서는 변경되거나 다운되거나 사라질 수 있습니다. 신중하게 진행하시기 바랍니다."</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 4680236..ec07794 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -110,7 +110,7 @@
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Экранды жаздырасызбы?"</string>
     <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_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>
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Иштетүү"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Туташты"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Чогуу угуу"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Сакталды"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ажыратуу"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"иштетүү"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Спутник, байланыш жакшы"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Спутник, байланыш бар"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Спутник SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Шашылыш чалуулар же SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Жумуш профили"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Баарына эле жага бербейт"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner Android колдонуучу интерфейсин жөнгө салып жана ыңгайлаштыруунун кошумча ыкмаларын сунуштайт. Бул сынамык функциялар кийинки чыгарылыштарда өзгөрүлүп, бузулуп же жоголуп кетиши мүмкүн. Абайлап колдонуңуз."</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index edb8fa3..5ac2a6f 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"ໃຊ້ Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"ເຊື່ອມຕໍ່ແລ້ວ"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"ການແບ່ງປັນສຽງ"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ບັນທຶກແລ້ວ"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ຕັດການເຊື່ອມຕໍ່"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ເປີດນຳໃຊ້"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ດາວທຽມ, ການເຊື່ອມຕໍ່ດີ"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ດາວທຽມ, ການເຊື່ອມຕໍ່ທີ່ພ້ອມນຳໃຊ້"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS ດາວທຽມ"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"ໂທສຸກເສີນ ຫຼື SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"​ໂປຣ​ໄຟລ໌​ບ່ອນ​ເຮັດ​ວຽກ"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"ມ່ວນຊື່ນສຳລັບບາງຄົນ ແຕ່ບໍ່ແມ່ນສຳລັບທຸກຄົນ"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner ໃຫ້ທ່ານມີວິທີພິເສດຕື່ມອີກໃນການປັບປ່ຽນ ແລະຕົບແຕ່ງສ່ວນຕໍ່ປະສານຜູ້ໃຊ້ຂອງ Android. ຄຸນສົມບັດທົດລອງໃຊ້ເຫຼົ່ານີ້ອາດຈະປ່ຽນແປງ, ຢຸດເຊົາ ຫຼືຫາຍໄປໃນການວາງຈຳໜ່າຍໃນອະນາຄົດ. ຈົ່ງດຳເນີນຕໍ່ດ້ວຍຄວາມລະມັດລະວັງ."</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index a9a0e73..0516504 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"„Bluetooth“ naudojimas"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Prisijungta"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Garso įrašų bendrinimas"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Išsaugota"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"atjungti"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"suaktyvinti"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Palydovas, geras ryšys"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Palydovas, pasiekiamas ryšys"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Prisijungimas prie palydovo kritiniu atveju"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Skambučiai pagalbos numeriu arba pagalbos iškvietimas kritiniu atveju"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Darbo profilis"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Smagu, bet ne visada"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Sistemos naudotojo sąsajos derinimo priemonė suteikia papildomų galimybių pagerinti ir tinkinti „Android“ naudotojo sąsają. Šios eksperimentinės funkcijos gali pasikeisti, nutrūkti ar išnykti iš būsimų laidų. Tęskite atsargiai."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index d1e97a6..baf03e2 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Izmantot Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Savienojums izveidots"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Audio kopīgošana"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saglabāta"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"atvienot"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivizēt"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelīts, labs savienojums"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelīts, ir pieejams savienojums"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satelīta SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Ārkārtas izsaukumi vai ārkārtas zvani"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Darba profils"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Jautri dažiem, bet ne visiem"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Sistēmas saskarnes regulators sniedz papildu veidus, kā mainīt un pielāgot Android lietotāja saskarni. Nākamajās versijās šīs eksperimentālās funkcijas var tikt mainītas, bojātas vai to darbība var tikt pārtraukta. Turpinot esiet uzmanīgs."</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 7691ae6..24bdae3 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Користи Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Поврзано"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Споделување аудио"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Зачувано"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"прекини врска"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активирај"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Добра сателитска врска"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Достапна е сателитска врска"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Сателитски SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Итни повици или SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Работен профил"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Забава за некои, но не за сите"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Адаптерот на УИ на системот ви дава дополнителни начини за дотерување и приспособување на корисничкиот интерфејс на Android. Овие експериментални функции можеби ќе се изменат, расипат или ќе исчезнат во следните изданија. Продолжете со претпазливост."</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 8c0378a..32f840e 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth ഉപയോഗിക്കുക"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"കണക്‌റ്റ് ചെയ്‌തു"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"ഓഡിയോ പങ്കിടൽ"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"സംരക്ഷിച്ചു"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"വിച്ഛേദിക്കുക"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"സജീവമാക്കുക"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"സാറ്റലൈറ്റ്, മികച്ച കണക്ഷൻ"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"സാറ്റലൈറ്റ്, കണക്ഷൻ ലഭ്യമാണ്"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"സാറ്റലൈറ്റ് SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"എമർജൻസി കോൾ അല്ലെങ്കിൽ SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"ചിലർക്ക് വിനോദം, എന്നാൽ എല്ലാവർക്കുമില്ല"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Android ഉപയോക്തൃ ഇന്റർഫേസ് ആവശ്യമുള്ള രീതിയിൽ മാറ്റുന്നതിനും ഇഷ്ടാനുസൃതമാക്കുന്നതിനും സിസ്റ്റം UI ട്യൂണർ നിങ്ങൾക്ക് അധിക വഴികൾ നൽകുന്നു. ഭാവി റിലീസുകളിൽ ഈ പരീക്ഷണാത്മക ഫീച്ചറുകൾ മാറ്റുകയോ നിർത്തുകയോ അപ്രത്യക്ഷമാവുകയോ ചെയ്തേക്കാം. ശ്രദ്ധയോടെ മുന്നോട്ടുപോകുക."</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index bfd48a4..d229589 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth-г ашиглах"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Холбогдсон"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Аудио хуваалцах"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Хадгалсан"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"салгах"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"идэвхжүүлэх"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Хиймэл дагуул, холболт сайн байна"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Хиймэл дагуул, холболт боломжтой"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Хиймэл дагуул SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Яаралтай дуудлага эсвэл SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Ажлын профайл"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Зарим хүнд хөгжилтэй байж болох ч бүх хүнд тийм биш"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Системийн UI Tохируулагч нь Android хэрэглэгчийн интерфэйсийг тааруулах, өөрчлөх нэмэлт аргыг зааж өгөх болно. Эдгээр туршилтын тохиргоо нь цаашид өөрчлөгдөх, эвдрэх, алга болох магадлалтай. Үйлдлийг болгоомжтой хийнэ үү."</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index d124ce3..5ec388d 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"ब्‍लूटूथ वापरा"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"कनेक्ट केले"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"ऑडिओ शेअरिंग"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"सेव्ह केले"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"डिस्कनेक्ट करा"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ॲक्टिव्हेट करा"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"सॅटेलाइट, चांगले कनेक्शन"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"सॅटेलाइट, कनेक्शन उपलब्ध"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"सॅटेलाइट SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"आणीबाणी कॉल किंवा SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"कार्य प्रोफाईल"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"सर्वांसाठी नाही तर काहींसाठी मजेदार असू शकते"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"सिस्टम UI ट्युनर आपल्‍याला Android यूझर इंटरफेस ट्विक आणि कस्टमाइझ करण्‍याचे अनेक प्रकार देते. ही प्रयोगात्मक वैशिष्‍ट्ये बदलू शकतात, खंडित होऊ शकतात किंवा भविष्‍यातील रिलीज मध्‍ये कदाचित दिसणार नाहीत. सावधगिरी बाळगून पुढे सुरू ठेवा."</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 8385682..9a9455a 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Gunakan Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Disambungkan"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Perkongsian Audio"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Disimpan"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"putuskan sambungan"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktifkan"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, sambungan yang baik"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, sambungan tersedia"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS via Satelit"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Panggilan kecemasan atau SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil kerja"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Menarik untuk sesetengah orang tetapi bukan untuk semua"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Penala UI Sistem memberi anda cara tambahan untuk mengolah dan menyesuaikan antara muka Android. Ciri eksperimen ini boleh berubah, rosak atau hilang dalam keluaran masa hadapan. Teruskan dengan berhati-hati."</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 60c74c1..622b1d5 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"ဘလူးတုသ်သုံးရန်"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"ချိတ်ဆက်ထားသည်"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"အော်ဒီယို မျှဝေခြင်း"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"သိမ်းထားသည်"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ချိတ်ဆက်မှုဖြုတ်ရန်"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"စသုံးရန်"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ဂြိုဟ်တု၊ ချိတ်ဆက်မှု ကောင်းသည်"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ဂြိုဟ်တု၊ ချိတ်ဆက်မှု ရနိုင်သည်"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"အရေးပေါ်ဖုန်းခေါ်ခြင်း (သို့) SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"အလုပ် ပရိုဖိုင်"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"အချို့သူများ အတွက် ပျော်စရာ ဖြစ်ပေမဲ့ အားလုံး အတွက် မဟုတ်ပါ"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"စနစ် UI Tuner က သင့်အတွက် Android အသုံးပြုသူ အင်တာဖေ့စ်ကို ပြောင်းရန်နှင့် စိတ်ကြိုက်ပြုလုပ်ရန် နည်းလမ်း အပိုများကို သင့်အတွက် စီစဉ်ပေးသည်။ အနာဂတ်ဗားရှင်းများတွင် ဤစမ်းသပ်အင်္ဂါရပ်များမှာ ပြောင်းလဲ၊ ပျက်စီး သို့မဟုတ် ပျောက်ကွယ်သွားနိုင်သည်။ သတိဖြင့် ရှေ့ဆက်ပါ။"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 72ccd2c..1191844 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bruk Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Tilkoblet"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Lyddeling"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Lagret"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"koble fra"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiver"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellitt – god tilkobling"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellitt – tilkobling tilgjengelig"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS-alarm via satellitt"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Nødanrop eller SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Work-profil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Gøy for noen – ikke for alle"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Med System UI Tuner har du flere måter å justere og tilpasse Android-brukergrensesnittet på. Disse eksperimentelle funksjonene kan endres, avbrytes eller fjernes i fremtidige utgivelser. Fortsett med forbehold."</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index d680645..610a449 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"ब्लुटुथ प्रयोग गर्नुहोस्"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"कनेक्ट गरिएको छ"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"अडियो सेयरिङ"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"सेभ गरिएको छ"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"डिस्कनेक्ट गर्नुहोस्"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"एक्टिभेट गर्नुहोस्"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"स्याटलाइट, राम्रो कनेक्सन"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"स्याटलाइट, कनेक्सन उपलब्ध छ"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"स्याटलाइट SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"आपत्कालीन कल वा SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"कार्य प्रोफाइल"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"केहीका लागि रमाइलो हुन्छ तर सबैका लागि होइन"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"सिस्टम UI ट्युनरले तपाईँलाई Android प्रयोगकर्ता इन्टरफेस  कस्टम गर्न र ट्विक गर्न थप तरिकाहरू प्रदान गर्छ। यी प्रयोगात्मक सुविधाहरू भावी विमोचनमा परिवर्तन हुन, बिग्रिन वा हराउन सक्ने छन्। सावधानीपूर्वक अगाडि बढ्नुहोस्।"</string>
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index 21f1cfb..c1eff5f 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -16,7 +16,11 @@
 
   NOTE: You might also want to edit: core/res/res/values-night/*.xml
   -->
-<resources>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+    <!-- The dark background color behind the shade -->
+    <color name="shade_scrim_background_dark">@androidprv:color/system_under_surface_dark</color>
+
     <!-- The color of the legacy notifications with customs backgrounds (gingerbread and lollipop.)
     It's fine to override this color since at that point the shade was dark. -->
     <color name="notification_legacy_background_color">@color/GM2_grey_900</color>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 6a675b8..404d768 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth gebruiken"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Verbonden"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Audio delen"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Opgeslagen"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"loskoppelen"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activeren"</string>
@@ -629,7 +631,7 @@
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Instellingen"</string>
     <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Live ondertiteling"</string>
     <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume verlaagd naar een veiliger niveau"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Het hoofdtelefoonvolume is langer dan de aanbevolen tijd hoog geweest"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Het koptelefoonvolume is langer dan de aanbevolen tijd hoog geweest"</string>
     <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Het hoofdtelefoonvolume overschrijdt de veiligheidslimiet voor deze week"</string>
     <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Blijven luisteren"</string>
     <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Volume omlaag"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliet, goede verbinding"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliet, verbinding beschikbaar"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS via satelliet"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Noodoproepen of SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Werkprofiel"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Leuk voor sommige gebruikers, maar niet voor iedereen"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Met Systeem-UI-tuner beschikt u over extra manieren om de Android-gebruikersinterface aan te passen. Deze experimentele functies kunnen veranderen, vastlopen of verdwijnen in toekomstige releases. Ga voorzichtig verder."</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 6e63643..5b9d747 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"ବ୍ଲୁଟୁଥ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"କନେକ୍ଟ କରାଯାଇଛି"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"ଅଡିଓ ସେୟାରିଂ"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ସେଭ କରାଯାଇଛି"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ଡିସକନେକ୍ଟ କରନ୍ତୁ"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ଚାଲୁ କରନ୍ତୁ"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ସାଟେଲାଇଟ, ଭଲ କନେକ୍ସନ"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ସାଟେଲାଇଟ, କନେକ୍ସନ ଉପଲବ୍ଧ"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"ସେଟେଲାଇଟ SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"ଜରୁରୀକାଳୀନ କଲ କିମ୍ବା SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"ୱର୍କ ପ୍ରୋଫାଇଲ୍‌"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"କେତେକଙ୍କ ପାଇଁ ମଜାଦାର, କିନ୍ତୁ ସମସ୍ତଙ୍କ ପାଇଁ ନୁହେଁ"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Android ୟୁଜର୍‍ ଇଣ୍ଟରଫେସ୍‍ ବଦଳାଇବାକୁ ତଥା ନିଜ ପସନ୍ଦ ଅନୁଯାୟୀ କରିବାକୁ ସିଷ୍ଟମ୍‍ UI ଟ୍ୟୁନର୍‍ ଆପଣଙ୍କୁ ଅତିରିକ୍ତ ଉପାୟ ପ୍ରଦାନ କରେ। ଏହି ପରୀକ୍ଷାମୂଳକ ସୁବିଧାମାନ ବଦଳିପାରେ, ଭାଙ୍ଗିପାରେ କିମ୍ବା ଭବିଷ୍ୟତର ରିଲିଜ୍‌ଗୁଡ଼ିକରେ ନଦେଖାଯାଇପାରେ। ସତର୍କତାର ସହ ଆଗକୁ ବଢ଼ନ୍ତୁ।"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index cd7790f..c9a45ba 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -110,7 +110,7 @@
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ਕੀ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ ਨੂੰ ਰਿਕਾਰਡ ਕਰਨਾ ਹੈ?"</string>
     <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_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>
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"ਬਲੂਟੁੱਥ ਵਰਤੋ"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"ਕਨੈਕਟ ਹੈ"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"ਆਡੀਓ ਸਾਂਝਾਕਰਨ"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ਰੱਖਿਅਤ ਕੀਤਾ ਗਿਆ"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ਕਿਰਿਆਸ਼ੀਲ ਕਰੋ"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ਸੈਟੇਲਾਈਟ, ਕਨੈਕਸ਼ਨ ਵਧੀਆ ਹੈ"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ਸੈਟੇਲਾਈਟ, ਕਨੈਕਸ਼ਨ ਉਪਲਬਧ ਹੈ"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"ਸੈਟੇਲਾਈਟ SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"ਐਮਰਜੈਂਸੀ ਕਾਲਾਂ ਜਾਂ ਸਹਾਇਤਾ"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"ਕੁਝ ਵਾਸਤੇ ਤਾਂ ਮਜ਼ੇਦਾਰ ਹੈ ਲੇਕਿਨ ਸਾਰਿਆਂ ਵਾਸਤੇ ਨਹੀਂ"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"ਸਿਸਟਮ UI ਟਿਊਨਰ ਤੁਹਾਨੂੰ Android ਵਰਤੋਂਕਾਰ ਇੰਟਰਫ਼ੇਸ ਤਬਦੀਲ ਕਰਨ ਅਤੇ ਵਿਉਂਤਬੱਧ ਕਰਨ ਲਈ ਵਾਧੂ ਤਰੀਕੇ ਦਿੰਦਾ ਹੈ। ਇਹ ਪ੍ਰਯੋਗਾਤਮਿਕ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਭਵਿੱਖ ਦੀ ਰੀਲੀਜ਼ ਵਿੱਚ ਬਦਲ ਸਕਦੀਆਂ ਹਨ, ਟੁੱਟ ਸਕਦੀਆਂ ਹਨ, ਜਾਂ ਅਲੋਪ ਹੋ ਸਕਦੀਆਂ ਹਨ। ਸਾਵਧਾਨੀ ਨਾਲ ਅੱਗੇ ਵੱਧੋ।"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index cf88172..f467409 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="4811759950673118541">"UI systemu"</string>
+    <string name="app_label" msgid="4811759950673118541">"Interfejs systemu"</string>
     <string name="battery_low_title" msgid="5319680173344341779">"Włączyć Oszczędzanie baterii?"</string>
     <string name="battery_low_description" msgid="3282977755476423966">"Masz już tylko <xliff:g id="PERCENTAGE">%s</xliff:g> baterii. Oszczędzanie baterii uruchamia ciemny motyw, ogranicza aktywność w tle i opóźnia powiadomienia."</string>
     <string name="battery_low_intro" msgid="5148725009653088790">"Oszczędzanie baterii uruchamia ciemny motyw, ogranicza aktywność w tle i opóźnia powiadomienia."</string>
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Używaj Bluetootha"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Połączone"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Udostępnianie dźwięku"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Zapisane"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"rozłącz"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktywuj"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelita – połączenie dobre"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelita – połączenie dostępne"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satelitarne połączenie alarmowe"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Połączenia alarmowe lub SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil służbowy"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Dobra zabawa, ale nie dla każdego"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Kalibrator System UI udostępnia dodatkowe sposoby dostrajania i dostosowywania interfejsu Androida. Te eksperymentalne funkcje mogą się zmienić, popsuć lub zniknąć w przyszłych wersjach. Zachowaj ostrożność."</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index c2c40db..154fc3d 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -300,6 +300,8 @@
     <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>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <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>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, conexão boa"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexão disponível"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS via satélite"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Chamadas de emergência ou SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabalho"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diversão para alguns, mas não para todos"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"O sintonizador System UI fornece maneiras adicionais de ajustar e personalizar a interface do usuário do Android. Esses recursos experimentais podem mudar, falhar ou desaparecer nas versões futuras. Prossiga com cuidado."</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index c52354f..d96c540 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Usar Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Ligado"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Partilha de áudio"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Guardado"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desassociar"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ativar"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, boa ligação"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, ligação disponível"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satélite SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Chamadas de emergência ou SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabalho"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diversão para alguns, mas não para todos"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"O Sintonizador da interface do sistema disponibiliza-lhe formas adicionais ajustar e personalizar a interface do utilizador do Android. Estas funcionalidades experimentais podem ser alteradas, deixar de funcionar ou desaparecer em versões futuras. Prossiga com cuidado."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index c2c40db..154fc3d 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -300,6 +300,8 @@
     <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>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <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>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, conexão boa"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexão disponível"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS via satélite"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Chamadas de emergência ou SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabalho"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diversão para alguns, mas não para todos"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"O sintonizador System UI fornece maneiras adicionais de ajustar e personalizar a interface do usuário do Android. Esses recursos experimentais podem mudar, falhar ou desaparecer nas versões futuras. Prossiga com cuidado."</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 1f7b7164..5e1eee3 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Folosește Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Conectat"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Permiterea accesului la audio"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvat"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"deconectează"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activează"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, conexiune bună"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, conexiune disponibilă"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS prin satelit"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Apeluri de urgență sau SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil de serviciu"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Distractiv pentru unii, dar nu pentru toată lumea"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner oferă modalități suplimentare de a ajusta și a personaliza interfața de utilizare Android. Aceste funcții experimentale pot să se schimbe, să se blocheze sau să dispară din versiunile viitoare. Continuă cu prudență."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 0b545ce..e938ca0 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Использовать"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Подключено"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Отправка аудио"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Сохранено"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"отключить"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активировать"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Спутниковая связь, хорошее качество соединения"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Доступно соединение по спутниковой связи"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Спутниковый SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Экстренные вызовы или спутниковый SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Рабочий профиль"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Внимание!"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner позволяет настраивать интерфейс устройства Android по вашему вкусу. В будущем эта экспериментальная функция может измениться, перестать работать или исчезнуть."</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index b34b8a3..7b2b2be 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"බ්ලූටූත් භාවිතා කරන්න"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"සම්බන්ධිතයි"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"ශ්‍රව්‍ය බෙදා ගැනීම"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"සුරැකිණි"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"විසන්ධි කරන්න"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"සක්‍රිය කරන්න"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"චන්ද්‍රිකාව, හොඳ සම්බන්ධතාවයක්"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"චන්ද්‍රිකාව, සම්බන්ධතාවය තිබේ"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"චන්ද්‍රිකා SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"හදිසි ඇමතුම් හෝ SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"කාර්යාල පැතිකඩ"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"සමහරක් දේවල් වලට විනෝදයි, නමුත් සියල්ලටම නොවේ"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"පද්ධති UI සුසරකය ඔබට Android පරිශීලක අතුරු මුහුණත වෙනස් කිරීමට හෝ අභිරුචිකරණය කිරීමට අමතර ක්‍රම ලබා දේ. මෙම පර්යේෂණාත්මක අංග ඉදිරි නිකුත් වීම් වල වෙනස් වීමට, වැඩ නොකිරීමට, හෝ නැතිවීමට හැක. ප්‍රවේශමෙන් ඉදිරියට යන්න."</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index b1983b8..877e87b 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Používať Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Pripojené"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Zdieľanie zvuku"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Uložené"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"odpojiť"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivovať"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobrá kvalita pripojenia"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, pripojenie je k dispozícii"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Pomoc cez satelit"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Tiesňové volania alebo pomoc v tiesni"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Pracovný profil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Pri používaní tuneru postupujte opatrne"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Tuner používateľského rozhrania systému poskytujte ďalšie spôsoby ladenia a prispôsobenia používateľského rozhrania Android. Tieto experimentálne funkcie sa môžu v budúcich verziách zmeniť, ich poskytovanie môže byť prerušené alebo môžu byť odstránené. Pokračujte opatrne."</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index a3b042e..22c5293 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Uporabi Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Povezano"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Deljenje zvoka"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Shranjeno"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekinitev povezave"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiviranje"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobra povezava"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, povezava je na voljo"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS prek satelita"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Klici v sili ali SOS prek satelita"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Delovni profil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Zabavno za nekatere, a ne za vse"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Uglaševalnik uporabniškega vmesnika sistema vam omogoča dodatne načine za spreminjanje in prilagajanje uporabniškega vmesnika Android. Te poskusne funkcije lahko v prihodnjih izdajah kadar koli izginejo, se spremenijo ali pokvarijo. Bodite previdni."</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 4cba527..a864df9 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Përdor Bluetooth-in"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Lidhur"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Ndarja e audios"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Ruajtur"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"shkëput"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivizo"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Sateliti. Lidhje e mirë"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Sateliti. Ofrohet lidhje"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS satelitor"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Telefonatat e urgjencës ose SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profili i punës"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Argëtim për disa, por jo për të gjithë!"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Sintonizuesi i Sistemit të Ndërfaqes së Përdoruesit të jep mënyra shtesë për të tërhequr dhe personalizuar ndërfaqen Android të përdoruesit. Këto funksione eksperimentale mund të ndryshojnë, prishen ose zhduken në versionet e ardhshme. Vazhdo me kujdes."</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 26c135b..91fdf2a 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Користи Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Повезано"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Дељење звука"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Сачувано"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"прекините везу"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активирајте"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Сателит, веза је добра"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Сателит, веза је доступна"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Хитна помоћ преко сателита"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Хитни позиви или хитна помоћ"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Пословни профил"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Забава за неке, али не за све"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Тјунер за кориснички интерфејс система вам пружа додатне начине за подешавање и прилагођавање Android корисничког интерфејса. Ове експерименталне функције могу да се промене, откажу или нестану у будућим издањима. Будите опрезни."</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 56cc442..dfd65bb 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Använd Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Ansluten"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Ljuddelning"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Sparad"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"koppla från"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivera"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellit, bra anslutning"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellit, anslutning tillgänglig"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS-larm via satellit"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Nödsamtal eller SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Jobbprofil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Kul för vissa, inte för alla"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Du kan använda inställningarna för systemgränssnitt för att justera användargränssnittet i Android. Dessa experimentfunktioner kan när som helst ändras, sluta fungera eller försvinna. Använd med försiktighet."</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index db237b5..809d2c4 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -124,7 +124,7 @@
     <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Inarekodi skrini na sauti"</string>
     <string name="screenrecord_taps_label" msgid="1595690528298857649">"Onyesha sehemu za kugusa kwenye skrini"</string>
     <string name="screenrecord_stop_label" msgid="72699670052087989">"Acha"</string>
-    <string name="screenrecord_share_label" msgid="5025590804030086930">"Shiriki"</string>
+    <string name="screenrecord_share_label" msgid="5025590804030086930">"Tuma"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Imehifadhi rekodi ya skrini"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Gusa ili uangalie"</string>
     <string name="screenrecord_save_error" msgid="5862648532560118815">"Hitilafu imetokea wakati wa kuhifadhi rekodi ya skrini"</string>
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Tumia Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Imeunganishwa"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Kusikiliza Pamoja"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Imehifadhiwa"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ondoa"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"anza kutumia"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Setilaiti, muunganisho thabiti"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Setilaiti, muunganisho unapatikana"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Msaada kupitia Setilaiti"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Simu za dharura"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Wasifu wa kazini"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Kinafurahisha kwa baadhi ya watu lakini si wote"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Kirekebishi cha kiolesura cha mfumo kinakupa njia zaidi za kugeuza na kubadilisha kiolesura cha Android ili kikufae. Vipengele hivi vya majaribio vinaweza kubadilika, kuharibika au kupotea katika matoleo ya siku zijazo. Endelea kwa uangalifu."</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index e617e88..ee8e11f4 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"புளூடூத்தைப் பயன்படுத்துதல்"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"இணைக்கப்பட்டது"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"ஆடியோ பகிர்வு"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"சேமிக்கப்பட்டது"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"இணைப்பு நீக்கும்"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"செயல்படுத்தும்"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"சாட்டிலைட், நிலையான இணைப்பு"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"சாட்டிலைட், இணைப்பு கிடைக்கிறது"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"சாட்டிலைட் SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"அவசர அழைப்புகள் அல்லது SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"பணிக் கணக்கு"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"சில வேடிக்கையாக இருந்தாலும் கவனம் தேவை"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner, Android பயனர் இடைமுகத்தை மாற்றவும் தனிப்பயனாக்கவும் கூடுதல் வழிகளை வழங்குகிறது. இந்தப் பரிசோதனைக்குரிய அம்சங்கள் எதிர்கால வெளியீடுகளில் மாற்றப்படலாம், இடைநிறுத்தப்படலாம் அல்லது தோன்றாமல் போகலாம். கவனத்துடன் தொடரவும்."</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index b45e82b..d09f3ec 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"బ్లూటూత్ వాడండి"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"కనెక్ట్ అయింది"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"ఆడియో షేరింగ్"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"సేవ్ అయ్యింది"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"డిస్‌కనెక్ట్ చేయండి"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"యాక్టివేట్ చేయండి"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"శాటిలైట్, కనెక్షన్ బాగుంది"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"శాటిలైట్, కనెక్షన్ అందుబాటులో ఉంది"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"ఎమర్జెన్సీ శాటిలైట్ సహాయం"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"ఎమర్జెన్సీ కాల్స్ లేదా SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"ఆఫీస్ ప్రొఫైల్‌"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"కొందరికి సరదాగా ఉంటుంది కానీ అందరికీ అలాగే ఉండదు"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"సిస్టమ్ UI ట్యూనర్ Android వినియోగదారు ఇంటర్‌ఫేస్‌ను మెరుగుపరచడానికి మరియు అనుకూలంగా మార్చడానికి మీకు మరిన్ని మార్గాలను అందిస్తుంది. ఈ ప్రయోగాత్మక లక్షణాలు భవిష్యత్తు విడుదలల్లో మార్పుకు లోనవ్వచ్చు, తాత్కాలికంగా లేదా పూర్తిగా నిలిపివేయవచ్చు. జాగ్రత్తగా కొనసాగండి."</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 252fc05..ddea72f 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"ใช้บลูทูธ"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"เชื่อมต่อแล้ว"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"การแชร์เสียง"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"บันทึกแล้ว"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ยกเลิกการเชื่อมต่อ"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"เปิดใช้งาน"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ดาวเทียม, การเชื่อมต่อดี"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ดาวเทียม, การเชื่อมต่อที่พร้อมใช้งาน"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS ดาวเทียม"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"การโทรฉุกเฉินหรือ SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"โปรไฟล์งาน"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"เพลิดเพลินกับบางส่วนแต่ไม่ใช่ทั้งหมด"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"ตัวรับสัญญาณ UI ระบบช่วยให้คุณมีวิธีพิเศษในการปรับแต่งและกำหนดค่าส่วนติดต่อผู้ใช้ Android ฟีเจอร์รุ่นทดลองเหล่านี้อาจมีการเปลี่ยนแปลง ขัดข้อง หรือหายไปในเวอร์ชันอนาคต โปรดดำเนินการด้วยความระมัดระวัง"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 04f52ea..7247757 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Gumamit ng Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Nakakonekta"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Pag-share ng Audio"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Na-save"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"idiskonekta"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"i-activate"</string>
@@ -629,7 +631,7 @@
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Mga Setting"</string>
     <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Instant Caption"</string>
     <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Ibinaba sa mas ligtas na level ang volume"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Naging malakas ang volume ng headphones nang mas matagal sa inirerekomenda"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Malakas ang volume ng headphones nang mas matagal sa inirerekomenda"</string>
     <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Lampas na sa ligtas na limitasyon para sa linggong ito ang volume ng headphone"</string>
     <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Magpatuloy sa pakikinig"</string>
     <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Hinaan"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, malakas ang koneksyon"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, may koneksyon"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Mga emergency na tawag o SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profile sa trabaho"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Masaya para sa ilan ngunit hindi para sa lahat"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Nagbibigay sa iyo ang Tuner ng System UI ng mga karagdagang paraan upang baguhin at i-customize ang user interface ng Android. Ang mga pang-eksperimentong feature na ito ay maaaring magbago, masira o mawala sa mga pagpapalabas sa hinaharap. Magpatuloy nang may pag-iingat."</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 19c9e0c..067d207 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth\'u kullan"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Bağlandı"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Ses Paylaşımı"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Kaydedildi"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"bağlantıyı kes"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"etkinleştir"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Uydu, bağlantı güçlü"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Uydu, bağlantı mevcut"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Acil Uydu Bağlantısı"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Acil durum aramaları veya acil yardım"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"İş profili"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Bazıları için eğlenceliyken diğerleri için olmayabilir"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Sistem Kullanıcı Arayüzü Ayarlayıcı, Android kullanıcı arayüzünde değişiklikler yapmanız ve arayüzü özelleştirmeniz için ekstra yollar sağlar. Bu deneysel özellikler değişebilir, bozulabilir veya gelecekteki sürümlerde yer almayabilir. Dikkatli bir şekilde devam edin."</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 8af4120..7ffb958 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Увімкнути Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Підключено"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Надсилання аудіо"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Збережено"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"від’єднати"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активувати"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Хороше з’єднання із супутником"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Доступне з’єднання із супутником"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Супутниковий сигнал SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Екстрені виклики або сигнал SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Робочий профіль"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Це цікаво, але будьте обачні"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner пропонує нові способи налаштувати та персоналізувати інтерфейс користувача Android. Ці експериментальні функції можуть змінюватися, не працювати чи зникати в майбутніх версіях. Будьте обачні."</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index dd27515..b2d4a11 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"بلوٹوتھ استعمال کریں"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"منسلک ہے"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"آڈیو کا اشتراک"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"محفوظ ہے"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"غیر منسلک کریں"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"فعال کریں"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"سیٹلائٹ، کنکشن اچھا ہے"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"سیٹلائٹ، کنکشن دستیاب ہے"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"‏سیٹلائٹ SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"‏ایمرجنسی کالز یا SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"دفتری پروفائل"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"کچھ کیلئے دلچسپ لیکن سبھی کیلئے نہیں"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"‏سسٹم UI ٹیونر Android صارف انٹر فیس میں ردوبدل کرنے اور اسے حسب ضرورت بنانے کیلئے آپ کو اضافی طریقے دیتا ہے۔ یہ تجرباتی خصوصیات مستقبل کی ریلیزز میں تبدیل ہو سکتی، رک سکتی یا غائب ہو سکتی ہیں۔ احتیاط کے ساتھ آگے بڑھیں۔"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index b0ba287..4b488a25 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth ishlatish"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Ulangan"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Audio ulashuvi"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saqlangan"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"uzish"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"faollashtirish"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Sputnik, aloqa sifati yaxshi"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Sputnik, aloqa mavjud"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Sputnik SOS"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Favqulodda chaqiruvlar yoki SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Ish profili"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diqqat!"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner yordamida siz Android foydalanuvchi interfeysini tuzatish va o‘zingizga moslashtirishingiz mumkin. Ushbu tajribaviy funksiyalar o‘zgarishi, buzilishi yoki keyingi versiyalarda olib tashlanishi mumkin. Ehtiyot bo‘lib davom eting."</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index b6c6967..2e06f72 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bật Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Đã kết nối"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Chia sẻ âm thanh"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Đã lưu"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ngắt kết nối"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"kích hoạt"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Kết nối vệ tinh tốt"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Hiện có kết nối vệ tinh"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Liên lạc khẩn cấp qua vệ tinh"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Cuộc gọi khẩn cấp hoặc SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Hồ sơ công việc"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Thú vị đối với một số người nhưng không phải tất cả"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Bộ điều hướng giao diện người dùng hệ thống cung cấp thêm cho bạn những cách chỉnh sửa và tùy chỉnh giao diện người dùng Android. Những tính năng thử nghiệm này có thể thay đổi, hỏng hoặc biến mất trong các phiên bản tương lai. Hãy thận trọng khi tiếp tục."</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 9ce05a3..0a96fc2 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -107,7 +107,7 @@
     <string name="screenrecord_title" msgid="4257171601439507792">"屏幕录制器"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在处理屏幕录制视频"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持续显示屏幕录制会话通知"</string>
-    <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"要录制屏幕?"</string>
+    <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"要录制屏幕吗?"</string>
     <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_warning_entire_screen" msgid="1321758636709366068">"录制整个屏幕时,屏幕上显示的所有内容均会被录制。因此,请务必小心操作,谨防泄露密码、付款信息、消息、照片、音频、视频等。"</string>
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"启用蓝牙"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"已连接"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"音频分享"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"已保存"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"断开连接"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"启用"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"卫星,连接质量良好"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"卫星,可连接"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"卫星紧急呼救"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"紧急呼叫或紧急求救"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"工作资料"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"并不适合所有用户"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"系统界面调节工具可让您以更多方式调整及定制 Android 界面。在日后推出的版本中,这些实验性功能可能会变更、失效或消失。操作时请务必谨慎。"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index e8532be..6b5edff 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"使用藍牙"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"已連接"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"音訊分享功能"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"已儲存"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"解除連結"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"啟動"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"衛星,連線質素好"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"衛星,可以連線"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"緊急衛星連接"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"緊急電話或 SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"工作設定檔"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"這只是測試版本,並不包含完整功能"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"使用者介面調諧器讓你以更多方法修改和自訂 Android 使用者介面。但請小心,這些實驗功能可能會在日後發佈時更改、分拆或消失。"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index e049374..78cd289 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"使用藍牙"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"已連線"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"音訊分享"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"已儲存"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"取消連結"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"啟用"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"衛星,連線品質良好"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"衛星,可連線"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"緊急衛星連線"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"緊急電話或緊急求救"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"工作資料夾"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"有趣與否,見仁見智"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"系統使用者介面調整精靈可讓你透過其他方式,調整及自訂 Android 使用者介面。這些實驗性功能隨著版本更新可能會變更、損壞或消失,執行時請務必謹慎。"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index d85db55..8bcc3ed 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -300,6 +300,8 @@
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Sebenzisa iBluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Ixhunyiwe"</string>
     <string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Ukwabelana Ngokuqoshiwe"</string>
+    <!-- no translation found for quick_settings_bluetooth_device_audio_sharing_or_switch_active (3227408556754456024) -->
+    <skip />
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Ilondoloziwe"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"nqamula"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"yenza kusebenze"</string>
@@ -718,8 +720,7 @@
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Isethelayithi, uxhumano oluhle"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Isethelayithi, uxhumano luyatholakala"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Isethelayithi yokuxhumana ngezimo eziphuthumayo"</string>
-    <!-- no translation found for satellite_emergency_only_carrier_text (828510231597991206) -->
-    <skip />
+    <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Ikholi ephuthumayo noma i-SOS"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Iphrofayela yomsebenzi"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Kuyajabulisa kwabanye kodwa hhayi bonke"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Isishuni se-UI sesistimu sikunika izindlela ezingeziwe zokuhlobisa nokwenza ngezifiso isixhumanisi sokubona se-Android. Lezi zici zesilingo zingashintsha, zephuke, noma zinyamalale ekukhishweni kwangakusasa. Qhubeka ngokuqaphela."</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 8cf0fb2..a375264 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -29,7 +29,7 @@
     <color name="status_bar_icons_hover_color_dark">#38000000</color> <!-- 22% black -->
 
     <!-- The dark background color behind the shade -->
-    <color name="shade_scrim_background_dark">@*android:color/black</color>
+    <color name="shade_scrim_background_dark">@androidprv:color/system_under_surface_light</color>
 
     <!-- The color of the background in the separated list of the Global Actions menu -->
     <color name="global_actions_separated_background">#F5F5F5</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e5750d2..141d035 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1751,6 +1751,7 @@
 
     <!-- System UI Dialog -->
     <dimen name="dialog_title_text_size">24sp</dimen>
+    <dimen name="dialog_button_side_margin">8dp</dimen>
 
     <!-- Internet panel related dimensions -->
     <dimen name="internet_dialog_list_max_height">662dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d3d757b..be74291 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -3699,6 +3699,22 @@
           -->
     <string name="shortcut_helper_key_combinations_or_separator">or</string>
 
+    <!-- Keyboard touchpad tutorial scheduler-->
+    <!-- Notification title for launching keyboard tutorial [CHAR_LIMIT=100] -->
+    <string name="launch_keyboard_tutorial_notification_title">Navigate using your keyboard</string>
+    <!-- Notification text for launching keyboard tutorial [CHAR_LIMIT=100] -->
+    <string name="launch_keyboard_tutorial_notification_content">Learn keyboards shortcuts</string>
+
+    <!-- Notification title for launching touchpad tutorial [CHAR_LIMIT=100] -->
+    <string name="launch_touchpad_tutorial_notification_title">Navigate using your touchpad</string>
+    <!-- Notification text for launching keyboard tutorial [CHAR_LIMIT=100] -->
+    <string name="launch_touchpad_tutorial_notification_content">Learn touchpad gestures</string>
+
+    <!-- Notification title for launching keyboard tutorial [CHAR_LIMIT=100] -->
+    <string name="launch_keyboard_touchpad_tutorial_notification_title">Navigate using your keyboard and touchpad</string>
+    <!-- Notification text for launching keyboard tutorial [CHAR_LIMIT=100] -->
+    <string name="launch_keyboard_touchpad_tutorial_notification_content">Learn touchpad gestures, keyboards shortcuts, and more</string>
+
     <!-- TOUCHPAD TUTORIAL-->
     <!-- Label for button opening tutorial for back gesture on touchpad [CHAR LIMIT=NONE] -->
     <string name="touchpad_tutorial_back_gesture_button">Back gesture</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 3ef6243..a02c354 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -505,14 +505,14 @@
         <item name="onSurfaceVariant">?androidprv:attr/materialColorOnSurfaceVariant</item>
         <item name="outline">?androidprv:attr/materialColorOutline</item>
 
-        <item name="shadeActive">@color/material_dynamic_primary90</item>
-        <item name="onShadeActive">@color/material_dynamic_primary10</item>
-        <item name="onShadeActiveVariant">@color/material_dynamic_primary30</item>
-        <item name="shadeInactive">@color/material_dynamic_neutral20</item>
-        <item name="onShadeInactive">@color/material_dynamic_neutral90</item>
-        <item name="onShadeInactiveVariant">@color/material_dynamic_neutral_variant80</item>
-        <item name="shadeDisabled">@color/shade_disabled</item>
-        <item name="underSurface">@color/material_dynamic_neutral0</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="android:itemTextAppearance">@style/Control.MenuItem</item>
     </style>
 
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java
index 7733841..5e36539 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java
@@ -17,6 +17,7 @@
 package com.android.keyguard;
 
 import static com.android.systemui.DejankUtils.whitelistIpcs;
+import static com.android.systemui.Flags.msdlFeedback;
 
 import android.annotation.SuppressLint;
 import android.app.ActivityOptions;
@@ -46,6 +47,9 @@
 import com.android.systemui.util.EmergencyDialerConstants;
 import com.android.systemui.util.ViewController;
 
+import com.google.android.msdl.data.model.MSDLToken;
+import com.google.android.msdl.domain.MSDLPlayer;
+
 import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
@@ -67,6 +71,7 @@
     private final Executor mMainExecutor;
     private final Executor mBackgroundExecutor;
     private final SelectedUserInteractor mSelectedUserInteractor;
+    private final MSDLPlayer mMSDLPlayer;
 
     private final KeyguardUpdateMonitorCallback mInfoCallback =
             new KeyguardUpdateMonitorCallback() {
@@ -99,7 +104,8 @@
             MetricsLogger metricsLogger,
             LockPatternUtils lockPatternUtils,
             Executor mainExecutor, Executor backgroundExecutor,
-            SelectedUserInteractor selectedUserInteractor) {
+            SelectedUserInteractor selectedUserInteractor,
+            MSDLPlayer msdlPlayer) {
         super(view);
         mConfigurationController = configurationController;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -112,6 +118,7 @@
         mMainExecutor = mainExecutor;
         mBackgroundExecutor = backgroundExecutor;
         mSelectedUserInteractor = selectedUserInteractor;
+        mMSDLPlayer = msdlPlayer;
     }
 
     @Override
@@ -165,6 +172,9 @@
     @SuppressLint("MissingPermission")
     public void takeEmergencyCallAction() {
         mMetricsLogger.action(MetricsEvent.ACTION_EMERGENCY_CALL);
+        if (msdlFeedback()) {
+            mMSDLPlayer.playToken(MSDLToken.KEYPRESS_RETURN, null);
+        }
         if (mPowerManager != null) {
             mPowerManager.userActivity(SystemClock.uptimeMillis(), true);
         }
@@ -221,6 +231,7 @@
         private final Executor mMainExecutor;
         private final Executor mBackgroundExecutor;
         private final SelectedUserInteractor mSelectedUserInteractor;
+        private final MSDLPlayer mMSDLPlayer;
 
         @Inject
         public Factory(ConfigurationController configurationController,
@@ -233,7 +244,8 @@
                 LockPatternUtils lockPatternUtils,
                 @Main Executor mainExecutor,
                 @Background Executor backgroundExecutor,
-                SelectedUserInteractor selectedUserInteractor) {
+                SelectedUserInteractor selectedUserInteractor,
+                MSDLPlayer msdlPlayer) {
 
             mConfigurationController = configurationController;
             mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -246,6 +258,7 @@
             mMainExecutor = mainExecutor;
             mBackgroundExecutor = backgroundExecutor;
             mSelectedUserInteractor = selectedUserInteractor;
+            mMSDLPlayer = msdlPlayer;
         }
 
         /** Construct an {@link com.android.keyguard.EmergencyButtonController}. */
@@ -253,7 +266,7 @@
             return new EmergencyButtonController(view, mConfigurationController,
                     mKeyguardUpdateMonitor, mPowerManager, mActivityTaskManager, mShadeController,
                     mTelecomManager, mMetricsLogger, mLockPatternUtils, mMainExecutor,
-                    mBackgroundExecutor, mSelectedUserInteractor);
+                    mBackgroundExecutor, mSelectedUserInteractor, mMSDLPlayer);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 61f9800..2d28a18 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -35,7 +35,6 @@
 
 import android.app.ActivityManager;
 import android.app.admin.DevicePolicyManager;
-import android.app.admin.flags.Flags;
 import android.content.Intent;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
@@ -1140,12 +1139,7 @@
             int remainingBeforeWipe, int failedAttempts) {
         int userType = USER_TYPE_PRIMARY;
         if (expiringUserId == userId) {
-            int primaryUser = UserHandle.USER_SYSTEM;
-            if (Flags.headlessSingleUserFixes()) {
-                if (mainUserId != null) {
-                    primaryUser = mainUserId;
-                }
-            }
+            int primaryUser = mainUserId != null ? mainUserId : UserHandle.USER_SYSTEM;
             // TODO: http://b/23522538
             if (expiringUserId != primaryUser) {
                 userType = USER_TYPE_SECONDARY_USER;
diff --git a/packages/SystemUI/src/com/android/systemui/ambient/dagger/AmbientModule.kt b/packages/SystemUI/src/com/android/systemui/ambient/dagger/AmbientModule.kt
index b0314d8..476d54b 100644
--- a/packages/SystemUI/src/com/android/systemui/ambient/dagger/AmbientModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/ambient/dagger/AmbientModule.kt
@@ -32,5 +32,6 @@
 interface AmbientModule {
     companion object {
         const val TOUCH_HANDLERS = "touch_handlers"
+        const val LOGGING_NAME = "logging_name"
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/ambient/touch/TouchMonitor.java b/packages/SystemUI/src/com/android/systemui/ambient/touch/TouchMonitor.java
index 1be6f9e..0898134 100644
--- a/packages/SystemUI/src/com/android/systemui/ambient/touch/TouchMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/ambient/touch/TouchMonitor.java
@@ -18,6 +18,7 @@
 
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 
+import static com.android.systemui.ambient.dagger.AmbientModule.LOGGING_NAME;
 import static com.android.systemui.shared.Flags.bouncerAreaExclusion;
 import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
 
@@ -44,6 +45,9 @@
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.DisplayId;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.log.LogBuffer;
+import com.android.systemui.log.core.Logger;
+import com.android.systemui.log.dagger.CommunalTouchLog;
 import com.android.systemui.shared.system.InputChannelCompat;
 import com.android.systemui.util.display.DisplayHelper;
 
@@ -62,6 +66,8 @@
 import java.util.stream.Collectors;
 
 import javax.inject.Inject;
+import javax.inject.Named;
+
 
 /**
  * {@link TouchMonitor} is responsible for monitoring touches and gestures over the
@@ -73,6 +79,7 @@
     // This executor is used to protect {@code mActiveTouchSessions} from being modified
     // concurrently. Any operation that adds or removes values should use this executor.
     public String TAG = "DreamOverlayTouchMonitor";
+    private final Logger mLogger;
     private final Executor mMainExecutor;
     private final Executor mBackgroundExecutor;
 
@@ -116,6 +123,11 @@
             TouchSessionImpl touchSessionImpl) {
         return CallbackToFutureAdapter.getFuture(completer -> {
             mMainExecutor.execute(() -> {
+                mLogger.i(msg -> "Session popped, hashCode: " + msg.getInt1(), msg -> {
+                    msg.setInt1(touchSessionImpl.hashCode());
+                    return kotlin.Unit.INSTANCE;
+                });
+
                 if (mActiveTouchSessions.remove(touchSessionImpl)) {
                     touchSessionImpl.onRemoved();
 
@@ -269,6 +281,7 @@
      * When invoked, instantiates a new {@link InputSession} to monitor touch events.
      */
     private void startMonitoring() {
+        mLogger.i("startMonitoring(): monitoring started");
         stopMonitoring(true);
 
         if (bouncerAreaExclusion()) {
@@ -322,6 +335,12 @@
         }
 
         if (!mActiveTouchSessions.isEmpty() && !force) {
+            mLogger.i(msg -> "stopMonitoring(): waiting for sessions to end: " + msg.getStr1(),
+                    msg -> {
+                        msg.setStr1(mActiveTouchSessions.stream().map(Object::hashCode).map(
+                                Object::toString).collect(Collectors.joining(",")));
+                        return kotlin.Unit.INSTANCE;
+                    });
             mStopMonitoringPending = true;
             return;
         }
@@ -341,6 +360,8 @@
         mCurrentInputSession.dispose();
         mCurrentInputSession = null;
         mStopMonitoringPending = false;
+
+        mLogger.i("stopMonitoring(): monitoring finished");
     }
 
 
@@ -405,12 +426,29 @@
                         // created so the
                         // final session is correct.
                         sessionMap.forEach((dreamTouchHandler, touchSession)
-                                -> dreamTouchHandler.onSessionStart(touchSession));
+                                -> {
+                            if (ev instanceof MotionEvent motionEvent) {
+                                int x = Math.round(motionEvent.getX());
+                                int y = Math.round(motionEvent.getY());
+                                mLogger.i(
+                                        msg -> "Session start, handler: " + msg.getStr1() + ", x: "
+                                                + msg.getLong1() + ", y: " + msg.getLong2()
+                                                + ", hashCode: " + msg.getInt1(), msg -> {
+                                            msg.setStr1(
+                                                    dreamTouchHandler.getClass().getSimpleName());
+                                            msg.setLong1(x);
+                                            msg.setLong2(y);
+                                            msg.setInt1(touchSession.hashCode());
+                                            return kotlin.Unit.INSTANCE;
+                                        });
+                            }
+                            dreamTouchHandler.onSessionStart(touchSession);
+                        });
                     }
 
                     // Find active sessions and invoke on InputEvent.
                     mActiveTouchSessions.stream()
-                            .map(touchSessionStack -> touchSessionStack.getEventListeners())
+                            .map(TouchSessionImpl::getEventListeners)
                             .flatMap(Collection::stream)
                             .forEach(inputEventListener -> inputEventListener.onInputEvent(ev));
                 }
@@ -526,6 +564,8 @@
      *                            returned.
      * @param handlers            This set represents the {@link TouchHandler} instances that will
      *                            participate in touch handling.
+     * @param loggingName         Identifying string for this {@link TouchMonitor} that will be used
+     *                            when logging to {@link CommunalTouchLog}.
      */
     @Inject
     public TouchMonitor(
@@ -537,7 +577,9 @@
             ConfigurationInteractor configurationInteractor,
             Set<TouchHandler> handlers,
             IWindowManager windowManagerService,
-            @DisplayId int displayId) {
+            @DisplayId int displayId,
+            @Named(LOGGING_NAME) String loggingName,
+            @CommunalTouchLog LogBuffer logBuffer) {
         mDisplayId = displayId;
         mHandlers = handlers;
         mInputSessionFactory = inputSessionFactory;
@@ -547,6 +589,7 @@
         mDisplayHelper = displayHelper;
         mWindowManagerService = windowManagerService;
         mConfigurationInteractor = configurationInteractor;
+        mLogger = new Logger(logBuffer, loggingName + ":TouchMonitor");
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/ambient/touch/dagger/AmbientTouchComponent.kt b/packages/SystemUI/src/com/android/systemui/ambient/touch/dagger/AmbientTouchComponent.kt
index 390e53b..ba552c3 100644
--- a/packages/SystemUI/src/com/android/systemui/ambient/touch/dagger/AmbientTouchComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/ambient/touch/dagger/AmbientTouchComponent.kt
@@ -16,6 +16,7 @@
 package com.android.systemui.ambient.touch.dagger
 
 import androidx.lifecycle.LifecycleOwner
+import com.android.systemui.ambient.dagger.AmbientModule.Companion.LOGGING_NAME
 import com.android.systemui.ambient.dagger.AmbientModule.Companion.TOUCH_HANDLERS
 import com.android.systemui.ambient.touch.TouchHandler
 import com.android.systemui.ambient.touch.TouchMonitor
@@ -36,7 +37,8 @@
             @BindsInstance lifecycleOwner: LifecycleOwner,
             @BindsInstance
             @Named(TOUCH_HANDLERS)
-            touchHandlers: Set<@JvmSuppressWildcards TouchHandler>
+            touchHandlers: Set<@JvmSuppressWildcards TouchHandler>,
+            @BindsInstance @Named(LOGGING_NAME) loggingName: String,
         ): AmbientTouchComponent
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
index fcba425..3080e19 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.authentication.domain.interactor
 
-import android.app.admin.flags.Flags
 import android.os.UserHandle
 import com.android.internal.widget.LockPatternUtils
 import com.android.internal.widget.LockPatternView
@@ -289,12 +288,7 @@
     private suspend fun getWipeTarget(): WipeTarget {
         // Check which profile has the strictest policy for failed authentication attempts.
         val userToBeWiped = repository.getProfileWithMinFailedUnlockAttemptsForWipe()
-        val primaryUser =
-            if (Flags.headlessSingleUserFixes()) {
-                selectedUserInteractor.getMainUserId() ?: UserHandle.USER_SYSTEM
-            } else {
-                UserHandle.USER_SYSTEM
-            }
+        val primaryUser = selectedUserInteractor.getMainUserId() ?: UserHandle.USER_SYSTEM
         return when (userToBeWiped) {
             selectedUserInteractor.getSelectedUserId() ->
                 if (userToBeWiped == primaryUser) {
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
index cc8dce79..49dadce 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
@@ -2,13 +2,11 @@
 
 import android.view.ViewGroup
 import com.android.keyguard.KeyguardMessageAreaController
-import com.android.keyguard.ViewMediatorCallback
 import com.android.keyguard.dagger.KeyguardBouncerComponent
-import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
 import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor
-import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
 import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
 import com.android.systemui.bouncer.ui.BouncerDialogFactory
+import com.android.systemui.bouncer.ui.viewmodel.BouncerContainerViewModel
 import com.android.systemui.bouncer.ui.viewmodel.BouncerSceneContentViewModel
 import com.android.systemui.bouncer.ui.viewmodel.KeyguardBouncerViewModel
 import com.android.systemui.dagger.SysUISingleton
@@ -39,12 +37,9 @@
 data class ComposeBouncerDependencies
 @Inject
 constructor(
-    val legacyInteractor: PrimaryBouncerInteractor,
     val viewModelFactory: BouncerSceneContentViewModel.Factory,
     val dialogFactory: BouncerDialogFactory,
-    val authenticationInteractor: AuthenticationInteractor,
-    val viewMediatorCallback: ViewMediatorCallback?,
-    val selectedUserInteractor: SelectedUserInteractor,
+    val bouncerContainerViewModelFactory: BouncerContainerViewModel.Factory,
 )
 
 /**
@@ -63,12 +58,9 @@
             val deps = composeBouncerDependencies.get()
             ComposeBouncerViewBinder.bind(
                 view,
-                deps.legacyInteractor,
                 deps.viewModelFactory,
                 deps.dialogFactory,
-                deps.authenticationInteractor,
-                deps.selectedUserInteractor,
-                deps.viewMediatorCallback,
+                deps.bouncerContainerViewModelFactory,
             )
         } else {
             val deps = legacyBouncerDependencies.get()
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/ComposeBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/ComposeBouncerViewBinder.kt
index c4bbd9c..b5e54d5 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/ComposeBouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/ComposeBouncerViewBinder.kt
@@ -5,89 +5,55 @@
 import androidx.activity.OnBackPressedDispatcherOwner
 import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
 import androidx.compose.ui.platform.ComposeView
-import androidx.core.view.isVisible
+import androidx.core.view.isGone
 import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.repeatOnLifecycle
-import com.android.keyguard.ViewMediatorCallback
-import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
-import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
 import com.android.systemui.bouncer.ui.BouncerDialogFactory
 import com.android.systemui.bouncer.ui.composable.BouncerContainer
+import com.android.systemui.bouncer.ui.viewmodel.BouncerContainerViewModel
 import com.android.systemui.bouncer.ui.viewmodel.BouncerSceneContentViewModel
+import com.android.systemui.lifecycle.WindowLifecycleState
 import com.android.systemui.lifecycle.repeatWhenAttached
-import com.android.systemui.user.domain.interactor.SelectedUserInteractor
-import kotlinx.coroutines.flow.collectLatest
-import kotlinx.coroutines.launch
+import com.android.systemui.lifecycle.setSnapshotBinding
+import com.android.systemui.lifecycle.viewModel
+import kotlinx.coroutines.awaitCancellation
 
 /** View binder responsible for binding the compose version of the bouncer. */
 object ComposeBouncerViewBinder {
     fun bind(
         view: ViewGroup,
-        legacyInteractor: PrimaryBouncerInteractor,
         viewModelFactory: BouncerSceneContentViewModel.Factory,
         dialogFactory: BouncerDialogFactory,
-        authenticationInteractor: AuthenticationInteractor,
-        selectedUserInteractor: SelectedUserInteractor,
-        viewMediatorCallback: ViewMediatorCallback?,
+        bouncerContainerViewModelFactory: BouncerContainerViewModel.Factory,
     ) {
-        view.addView(
-            ComposeView(view.context).apply {
-                repeatWhenAttached {
-                    repeatOnLifecycle(Lifecycle.State.CREATED) {
-                        setViewTreeOnBackPressedDispatcherOwner(
-                            object : OnBackPressedDispatcherOwner {
-                                override val onBackPressedDispatcher =
-                                    OnBackPressedDispatcher().apply {
-                                        setOnBackInvokedDispatcher(
-                                            view.viewRootImpl.onBackInvokedDispatcher
-                                        )
-                                    }
-
-                                override val lifecycle: Lifecycle =
-                                    this@repeatWhenAttached.lifecycle
-                            }
-                        )
-                        setContent { BouncerContainer(viewModelFactory, dialogFactory) }
-                    }
-                }
-            }
-        )
-
         view.repeatWhenAttached {
-            repeatOnLifecycle(Lifecycle.State.CREATED) {
-                launch {
-                    legacyInteractor.isShowing.collectLatest { bouncerShowing ->
-                        view.isVisible = bouncerShowing
-                    }
-                }
-
-                launch {
-                    authenticationInteractor.onAuthenticationResult.collectLatest {
-                        authenticationSucceeded ->
-                        if (authenticationSucceeded) {
-                            // Some dismiss actions require that keyguard be dismissed right away or
-                            // deferred until something else later on dismisses keyguard (eg. end of
-                            // a hide animation).
-                            val deferKeyguardDone =
-                                legacyInteractor.bouncerDismissAction?.onDismissAction?.onDismiss()
-                            legacyInteractor.setDismissAction(null, null)
-
-                            viewMediatorCallback?.let {
-                                val selectedUserId = selectedUserInteractor.getSelectedUserId()
-                                if (deferKeyguardDone == true) {
-                                    it.keyguardDonePending(selectedUserId)
-                                } else {
-                                    it.keyguardDone(selectedUserId)
+            view.viewModel(
+                minWindowLifecycleState = WindowLifecycleState.ATTACHED,
+                factory = { bouncerContainerViewModelFactory.create() },
+                traceName = "ComposeBouncerViewBinder",
+            ) { viewModel ->
+                try {
+                    view.setViewTreeOnBackPressedDispatcherOwner(
+                        object : OnBackPressedDispatcherOwner {
+                            override val onBackPressedDispatcher =
+                                OnBackPressedDispatcher().apply {
+                                    setOnBackInvokedDispatcher(
+                                        view.viewRootImpl.onBackInvokedDispatcher
+                                    )
                                 }
-                            }
+
+                            override val lifecycle: Lifecycle = this@repeatWhenAttached.lifecycle
                         }
-                    }
-                }
-                launch {
-                    legacyInteractor.startingDisappearAnimation.collectLatest {
-                        it.run()
-                        legacyInteractor.hide()
-                    }
+                    )
+
+                    view.addView(
+                        ComposeView(view.context).apply {
+                            setContent { BouncerContainer(viewModelFactory, dialogFactory) }
+                        }
+                    )
+                    view.setSnapshotBinding { view.isGone = !viewModel.isVisible }
+                    awaitCancellation()
+                } finally {
+                    view.removeAllViews()
                 }
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerContainerViewModel.kt
new file mode 100644
index 0000000..d223657
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerContainerViewModel.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bouncer.ui.viewmodel
+
+import androidx.compose.runtime.getValue
+import com.android.keyguard.ViewMediatorCallback
+import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
+import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
+import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.lifecycle.Hydrator
+import com.android.systemui.user.domain.interactor.SelectedUserInteractor
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
+
+class BouncerContainerViewModel
+@AssistedInject
+constructor(
+    private val legacyInteractor: PrimaryBouncerInteractor,
+    private val authenticationInteractor: AuthenticationInteractor,
+    private val selectedUserInteractor: SelectedUserInteractor,
+    private val viewMediatorCallback: ViewMediatorCallback?,
+) : ExclusiveActivatable() {
+
+    private val hydrator = Hydrator("BouncerContainerViewModel")
+
+    val isVisible: Boolean by
+        hydrator.hydratedStateOf(traceName = "isVisible", source = legacyInteractor.isShowing)
+
+    override suspend fun onActivated(): Nothing {
+        coroutineScope {
+            launch {
+                authenticationInteractor.onAuthenticationResult.collect { authenticationSucceeded ->
+                    if (authenticationSucceeded) {
+                        // Some dismiss actions require that keyguard be dismissed right away or
+                        // deferred until something else later on dismisses keyguard (eg. end of
+                        // a hide animation).
+                        val deferKeyguardDone =
+                            legacyInteractor.bouncerDismissAction?.onDismissAction?.onDismiss()
+                        legacyInteractor.setDismissAction(null, null)
+
+                        viewMediatorCallback?.let {
+                            val selectedUserId = selectedUserInteractor.getSelectedUserId()
+                            if (deferKeyguardDone == true) {
+                                it.keyguardDonePending(selectedUserId)
+                            } else {
+                                it.keyguardDone(selectedUserId)
+                            }
+                        }
+                    }
+                }
+            }
+
+            launch {
+                legacyInteractor.startingDisappearAnimation.collect {
+                    it.run()
+                    legacyInteractor.hide()
+                }
+            }
+
+            hydrator.activate()
+        }
+    }
+
+    @AssistedFactory
+    interface Factory {
+        fun create(): BouncerContainerViewModel
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModel.kt
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneActionsViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModel.kt
index 2d57e5b..4fe6fc6 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModel.kt
@@ -22,7 +22,7 @@
 import com.android.compose.animation.scene.UserAction
 import com.android.compose.animation.scene.UserActionResult
 import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
-import com.android.systemui.scene.ui.viewmodel.SceneActionsViewModel
+import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import kotlinx.coroutines.flow.map
@@ -31,11 +31,11 @@
  * Models UI state for user actions that can lead to navigation to other scenes when showing the
  * bouncer scene.
  */
-class BouncerSceneActionsViewModel
+class BouncerUserActionsViewModel
 @AssistedInject
 constructor(
     private val bouncerInteractor: BouncerInteractor,
-) : SceneActionsViewModel() {
+) : UserActionsViewModel() {
 
     override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
         bouncerInteractor.dismissDestination
@@ -50,6 +50,6 @@
 
     @AssistedFactory
     interface Factory {
-        fun create(): BouncerSceneActionsViewModel
+        fun create(): BouncerUserActionsViewModel
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
index d2caefd..e1ba93c 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
@@ -76,7 +76,6 @@
     private final boolean mTestHarness;
     private final MetricsLogger mMetricsLogger;
     private int mIsFalseTouchCalls;
-    private FeatureFlags mFeatureFlags;
     private static final Queue<String> RECENT_INFO_LOG =
             new ArrayDeque<>(RECENT_INFO_LOG_SIZE + 1);
     private static final Queue<DebugSwipeRecord> RECENT_SWIPES =
@@ -186,8 +185,7 @@
             DoubleTapClassifier doubleTapClassifier, HistoryTracker historyTracker,
             KeyguardStateController keyguardStateController,
             AccessibilityManager accessibilityManager,
-            @TestHarness boolean testHarness,
-            FeatureFlags featureFlags) {
+            @TestHarness boolean testHarness) {
         mDataProvider = falsingDataProvider;
         mMetricsLogger = metricsLogger;
         mClassifiers = classifiers;
@@ -198,7 +196,6 @@
         mKeyguardStateController = keyguardStateController;
         mAccessibilityManager = accessibilityManager;
         mTestHarness = testHarness;
-        mFeatureFlags = featureFlags;
 
         mDataProvider.addSessionListener(mSessionListener);
         mDataProvider.addGestureCompleteListener(mGestureFinalizedListener);
@@ -399,8 +396,7 @@
                 || mDataProvider.isA11yAction()
                 || mDataProvider.isFromTrackpad()
                 || mDataProvider.isFromKeyboard()
-                || (mFeatureFlags.isEnabled(Flags.FALSING_OFF_FOR_UNFOLDED)
-                    && mDataProvider.isUnfolded());
+                || mDataProvider.isUnfolded();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index 1c263ae..ae2d401 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -475,7 +475,7 @@
                 mLifecycleOwner,
                 new HashSet<>(Arrays.asList(
                         dreamComplicationComponent.getHideComplicationTouchHandler(),
-                        dreamOverlayComponent.getCommunalTouchHandler())));
+                        dreamOverlayComponent.getCommunalTouchHandler())), TAG);
 
         setLifecycleStateLocked(Lifecycle.State.STARTED);
 
diff --git a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt
index 87eeebf..3105527 100644
--- a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt
@@ -24,8 +24,6 @@
 import com.android.systemui.contextualeducation.GestureType
 import com.android.systemui.contextualeducation.GestureType.ALL_APPS
 import com.android.systemui.contextualeducation.GestureType.BACK
-import com.android.systemui.contextualeducation.GestureType.HOME
-import com.android.systemui.contextualeducation.GestureType.OVERVIEW
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.education.dagger.ContextualEducationModule.EduClock
@@ -68,11 +66,9 @@
 
     private val keyboardShortcutTriggered: Flow<GestureType> = conflatedCallbackFlow {
         val listener = KeyGestureEventListener { event ->
+            // Only store keyboard shortcut time for gestures providing keyboard education
             val shortcutType =
                 when (event.keyGestureType) {
-                    KeyGestureEvent.KEY_GESTURE_TYPE_BACK -> BACK
-                    KeyGestureEvent.KEY_GESTURE_TYPE_HOME -> HOME
-                    KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS -> OVERVIEW
                     KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS -> ALL_APPS
                     else -> null
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index bb73f56..95cd9eb 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -98,9 +98,6 @@
     @JvmField
     val AUTO_PIN_CONFIRMATION = releasedFlag("auto_pin_confirmation", "auto_pin_confirmation")
 
-    // TODO(b/262859270): Tracking Bug
-    @JvmField val FALSING_OFF_FOR_UNFOLDED = releasedFlag("falsing_off_for_unfolded")
-
     /** Enables code to show contextual loyalty cards in wallet entrypoints */
     // TODO(b/294110497): Tracking Bug
     @JvmField
@@ -203,12 +200,6 @@
     @JvmField
     val INCOMPATIBLE_CHARGING_BATTERY_ICON = releasedFlag("incompatible_charging_battery_icon")
 
-    // TODO(b/293585143): Tracking Bug
-    val INSTANT_TETHER = releasedFlag("instant_tether")
-
-    // TODO(b/294588085): Tracking Bug
-    val WIFI_SECONDARY_NETWORKS = releasedFlag("wifi_secondary_networks")
-
     // TODO(b/290676905): Tracking Bug
     val NEW_SHADE_CARRIER_GROUP_MOBILE_ICONS = releasedFlag("new_shade_carrier_group_mobile_icons")
 
@@ -233,9 +224,6 @@
     // TODO(b/254512697): Tracking Bug
     val MEDIA_TAP_TO_TRANSFER = releasedFlag("media_tap_to_transfer")
 
-    // TODO(b/254512502): Tracking Bug
-    val MEDIA_SESSION_ACTIONS = unreleasedFlag("media_session_actions")
-
     // TODO(b/254512654): Tracking Bug
     @JvmField val DREAM_MEDIA_COMPLICATION = unreleasedFlag("dream_media_complication")
 
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt
index e8e1dd4..7ecacdc 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt
@@ -18,20 +18,20 @@
 
 import com.android.systemui.CoreStartable
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.inputdevice.tutorial.domain.interactor.TutorialSchedulerInteractor
+import com.android.systemui.inputdevice.tutorial.ui.TutorialNotificationCoordinator
 import com.android.systemui.shared.Flags.newTouchpadGesturesTutorial
 import dagger.Lazy
 import javax.inject.Inject
 
-/** A [CoreStartable] to launch a scheduler for keyboard and touchpad education */
+/** A [CoreStartable] to launch a scheduler for keyboard and touchpad tutorial notification */
 @SysUISingleton
 class KeyboardTouchpadTutorialCoreStartable
 @Inject
-constructor(private val tutorialSchedulerInteractor: Lazy<TutorialSchedulerInteractor>) :
+constructor(private val tutorialNotificationCoordinator: Lazy<TutorialNotificationCoordinator>) :
     CoreStartable {
     override fun start() {
         if (newTouchpadGesturesTutorial()) {
-            tutorialSchedulerInteractor.get().start()
+            tutorialNotificationCoordinator.get().start()
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt
index a8d7dad..cfc913f 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt
@@ -17,9 +17,7 @@
 package com.android.systemui.inputdevice.tutorial.domain.interactor
 
 import android.os.SystemProperties
-import android.util.Log
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType
 import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType.KEYBOARD
 import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType.TOUCHPAD
@@ -31,23 +29,22 @@
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.hours
 import kotlin.time.toKotlinDuration
-import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.merge
-import kotlinx.coroutines.launch
 
 /**
- * When the first time a keyboard or touchpad is connected, wait for [LAUNCH_DELAY], then launch the
- * tutorial as soon as there's a connected device
+ * When the first time a keyboard or touchpad is connected, wait for [LAUNCH_DELAY], and as soon as
+ * there's a connected device, show a notification to launch the tutorial.
  */
 @SysUISingleton
 class TutorialSchedulerInteractor
 @Inject
 constructor(
-    @Background private val backgroundScope: CoroutineScope,
     keyboardRepository: KeyboardRepository,
     touchpadRepository: TouchpadRepository,
     private val repo: TutorialSchedulerRepository
@@ -58,17 +55,6 @@
             TOUCHPAD to touchpadRepository.isAnyTouchpadConnected
         )
 
-    fun start() {
-        backgroundScope.launch {
-            // Merging two flows to ensure that launch tutorial is launched consecutively in order
-            // to avoid race condition
-            merge(touchpadScheduleFlow, keyboardScheduleFlow).collect {
-                val tutorialType = resolveTutorialType(it)
-                launchTutorial(tutorialType)
-            }
-        }
-    }
-
     private val touchpadScheduleFlow = flow {
         if (!repo.isLaunched(TOUCHPAD)) {
             schedule(TOUCHPAD)
@@ -95,14 +81,19 @@
     private suspend fun waitForDeviceConnection(deviceType: DeviceType) =
         isAnyDeviceConnected[deviceType]!!.filter { it }.first()
 
-    private suspend fun launchTutorial(tutorialType: TutorialType) {
-        if (tutorialType == TutorialType.KEYBOARD || tutorialType == TutorialType.BOTH)
-            repo.updateLaunchTime(KEYBOARD, Instant.now())
-        if (tutorialType == TutorialType.TOUCHPAD || tutorialType == TutorialType.BOTH)
-            repo.updateLaunchTime(TOUCHPAD, Instant.now())
-        // TODO: launch tutorial
-        Log.d(TAG, "Launch tutorial for $tutorialType")
-    }
+    // Merging two flows ensures that tutorial is launched consecutively to avoid race condition
+    val tutorials: Flow<TutorialType> =
+        merge(touchpadScheduleFlow, keyboardScheduleFlow).map {
+            val tutorialType = resolveTutorialType(it)
+
+            // TODO: notifying time is not oobe launching time - move these updates into oobe
+            if (tutorialType == TutorialType.KEYBOARD || tutorialType == TutorialType.BOTH)
+                repo.updateLaunchTime(KEYBOARD, Instant.now())
+            if (tutorialType == TutorialType.TOUCHPAD || tutorialType == TutorialType.BOTH)
+                repo.updateLaunchTime(TOUCHPAD, Instant.now())
+
+            tutorialType
+        }
 
     private suspend fun resolveTutorialType(deviceType: DeviceType): TutorialType {
         // Resolve the type of tutorial depending on which device are connected when the tutorial is
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/TutorialNotificationCoordinator.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/TutorialNotificationCoordinator.kt
new file mode 100644
index 0000000..5d9dda3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/TutorialNotificationCoordinator.kt
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.inputdevice.tutorial.ui
+
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import androidx.core.app.NotificationCompat
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.inputdevice.tutorial.domain.interactor.TutorialSchedulerInteractor
+import com.android.systemui.inputdevice.tutorial.domain.interactor.TutorialSchedulerInteractor.Companion.TAG
+import com.android.systemui.inputdevice.tutorial.domain.interactor.TutorialSchedulerInteractor.TutorialType
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_BOTH
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_KEY
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_KEYBOARD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_TOUCHPAD
+import com.android.systemui.res.R
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+
+/** When the scheduler is due, show a notification to launch tutorial */
+@SysUISingleton
+class TutorialNotificationCoordinator
+@Inject
+constructor(
+    @Background private val backgroundScope: CoroutineScope,
+    @Application private val context: Context,
+    private val tutorialSchedulerInteractor: TutorialSchedulerInteractor,
+    private val notificationManager: NotificationManager
+) {
+    fun start() {
+        backgroundScope.launch {
+            tutorialSchedulerInteractor.tutorials.collect { showNotification(it) }
+        }
+    }
+
+    // By sharing the same tag and id, we update the content of existing notification instead of
+    // creating multiple notifications
+    private fun showNotification(tutorialType: TutorialType) {
+        if (tutorialType == TutorialType.NONE) return
+
+        if (notificationManager.getNotificationChannel(CHANNEL_ID) == null)
+            createNotificationChannel()
+
+        // Replace "System UI" app name with "Android System"
+        val extras = Bundle()
+        extras.putString(
+            Notification.EXTRA_SUBSTITUTE_APP_NAME,
+            context.getString(com.android.internal.R.string.android_system_label)
+        )
+
+        val info = getNotificationInfo(tutorialType)!!
+        val notification =
+            NotificationCompat.Builder(context, CHANNEL_ID)
+                .setSmallIcon(R.drawable.ic_settings)
+                .setContentTitle(info.title)
+                .setContentText(info.text)
+                .setContentIntent(createPendingIntent(info.type))
+                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
+                .setAutoCancel(true)
+                .addExtras(extras)
+                .build()
+
+        notificationManager.notify(TAG, NOTIFICATION_ID, notification)
+    }
+
+    private fun createNotificationChannel() {
+        val channel =
+            NotificationChannel(
+                CHANNEL_ID,
+                context.getString(com.android.internal.R.string.android_system_label),
+                NotificationManager.IMPORTANCE_DEFAULT
+            )
+        notificationManager.createNotificationChannel(channel)
+    }
+
+    private fun createPendingIntent(tutorialType: String): PendingIntent {
+        val intent =
+            Intent(context, KeyboardTouchpadTutorialActivity::class.java).apply {
+                putExtra(INTENT_TUTORIAL_TYPE_KEY, tutorialType)
+                flags = Intent.FLAG_ACTIVITY_NEW_TASK
+            }
+        return PendingIntent.getActivity(
+            context,
+            /* requestCode= */ 0,
+            intent,
+            PendingIntent.FLAG_IMMUTABLE
+        )
+    }
+
+    private data class NotificationInfo(val title: String, val text: String, val type: String)
+
+    private fun getNotificationInfo(tutorialType: TutorialType): NotificationInfo? =
+        when (tutorialType) {
+            TutorialType.KEYBOARD ->
+                NotificationInfo(
+                    context.getString(R.string.launch_keyboard_tutorial_notification_title),
+                    context.getString(R.string.launch_keyboard_tutorial_notification_content),
+                    INTENT_TUTORIAL_TYPE_KEYBOARD
+                )
+            TutorialType.TOUCHPAD ->
+                NotificationInfo(
+                    context.getString(R.string.launch_touchpad_tutorial_notification_title),
+                    context.getString(R.string.launch_touchpad_tutorial_notification_content),
+                    INTENT_TUTORIAL_TYPE_TOUCHPAD
+                )
+            TutorialType.BOTH ->
+                NotificationInfo(
+                    context.getString(
+                        R.string.launch_keyboard_touchpad_tutorial_notification_title
+                    ),
+                    context.getString(
+                        R.string.launch_keyboard_touchpad_tutorial_notification_content
+                    ),
+                    INTENT_TUTORIAL_TYPE_BOTH
+                )
+            TutorialType.NONE -> null
+        }
+
+    companion object {
+        private const val CHANNEL_ID = "TutorialSchedulerNotificationChannel"
+        private const val NOTIFICATION_ID = 5566
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt
index 8debe79..1adc285 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt
@@ -54,6 +54,7 @@
         const val INTENT_TUTORIAL_TYPE_KEY = "tutorial_type"
         const val INTENT_TUTORIAL_TYPE_TOUCHPAD = "touchpad"
         const val INTENT_TUTORIAL_TYPE_KEYBOARD = "keyboard"
+        const val INTENT_TUTORIAL_TYPE_BOTH = "both"
     }
 
     private val vm by
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
index 7899971..5bb7b64 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
@@ -22,7 +22,6 @@
 import android.annotation.SuppressLint
 import android.graphics.Point
 import android.graphics.Rect
-import android.os.VibrationAttributes
 import android.util.Log
 import android.view.HapticFeedbackConstants
 import android.view.View
@@ -41,6 +40,7 @@
 import com.android.app.tracing.coroutines.launch
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.jank.InteractionJankMonitor.CUJ_SCREEN_OFF_SHOW_AOD
+import com.android.keyguard.AuthInteractionProperties
 import com.android.systemui.Flags.msdlFeedback
 import com.android.systemui.Flags.newAodTransition
 import com.android.systemui.common.shared.model.Icon
@@ -82,7 +82,6 @@
 import com.android.systemui.util.ui.stopAnimating
 import com.android.systemui.util.ui.value
 import com.google.android.msdl.data.model.MSDLToken
-import com.google.android.msdl.domain.InteractionProperties
 import com.google.android.msdl.domain.MSDLPlayer
 import kotlin.math.min
 import kotlinx.coroutines.CoroutineDispatcher
@@ -358,14 +357,10 @@
                         launch {
                             deviceEntryHapticsInteractor.playSuccessHaptic.collect {
                                 if (msdlFeedback()) {
-                                    val properties =
-                                        object : InteractionProperties {
-                                            override val vibrationAttributes: VibrationAttributes =
-                                                VibrationAttributes.createForUsage(
-                                                    VibrationAttributes.USAGE_HARDWARE_FEEDBACK
-                                                )
-                                        }
-                                    msdlPlayer?.playToken(MSDLToken.UNLOCK, properties)
+                                    msdlPlayer?.playToken(
+                                        MSDLToken.UNLOCK,
+                                        authInteractionProperties
+                                    )
                                 } else {
                                     vibratorHelper.performHapticFeedback(
                                         view,
@@ -378,14 +373,10 @@
                         launch {
                             deviceEntryHapticsInteractor.playErrorHaptic.collect {
                                 if (msdlFeedback()) {
-                                    val properties =
-                                        object : InteractionProperties {
-                                            override val vibrationAttributes: VibrationAttributes =
-                                                VibrationAttributes.createForUsage(
-                                                    VibrationAttributes.USAGE_HARDWARE_FEEDBACK
-                                                )
-                                        }
-                                    msdlPlayer?.playToken(MSDLToken.FAILURE, properties)
+                                    msdlPlayer?.playToken(
+                                        MSDLToken.FAILURE,
+                                        authInteractionProperties
+                                    )
                                 } else {
                                     vibratorHelper.performHapticFeedback(
                                         view,
@@ -660,6 +651,7 @@
     private val lockIcon = R.id.lock_icon_view
     private val deviceEntryIcon = R.id.device_entry_icon_view
     private val nsslPlaceholderId = R.id.nssl_placeholder
+    private val authInteractionProperties = AuthInteractionProperties()
 
     private const val ID = "occluding_app_device_entry_unlock_msg"
     private const val AOD_ICONS_APPEAR_DURATION: Long = 200
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt
index 9f68210..a021de4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt
@@ -43,23 +43,22 @@
     val deviceEntryIconViewModel: DeviceEntryIconViewModel,
     keyguardTransitionInteractor: KeyguardTransitionInteractor,
     configurationInteractor: ConfigurationInteractor,
-    lockscreenToAodTransitionViewModel: LockscreenToAodTransitionViewModel,
-    aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
-    goneToAodTransitionViewModel: GoneToAodTransitionViewModel,
-    primaryBouncerToAodTransitionViewModel: PrimaryBouncerToAodTransitionViewModel,
-    occludedToAodTransitionViewModel: OccludedToAodTransitionViewModel,
-    occludedToLockscreenTransitionViewModel: OccludedToLockscreenTransitionViewModel,
-    dreamingToLockscreenTransitionViewModel: DreamingToLockscreenTransitionViewModel,
     alternateBouncerToAodTransitionViewModel: AlternateBouncerToAodTransitionViewModel,
-    goneToLockscreenTransitionViewModel: GoneToLockscreenTransitionViewModel,
-    goneToDozingTransitionViewModel: GoneToDozingTransitionViewModel,
-    primaryBouncerToDozingTransitionViewModel: PrimaryBouncerToDozingTransitionViewModel,
-    lockscreenToDozingTransitionViewModel: LockscreenToDozingTransitionViewModel,
-    dozingToLockscreenTransitionViewModel: DozingToLockscreenTransitionViewModel,
     alternateBouncerToDozingTransitionViewModel: AlternateBouncerToDozingTransitionViewModel,
+    aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
+    dozingToLockscreenTransitionViewModel: DozingToLockscreenTransitionViewModel,
     dreamingToAodTransitionViewModel: DreamingToAodTransitionViewModel,
-    primaryBouncerToLockscreenTransitionViewModel: PrimaryBouncerToLockscreenTransitionViewModel,
+    dreamingToLockscreenTransitionViewModel: DreamingToLockscreenTransitionViewModel,
+    goneToAodTransitionViewModel: GoneToAodTransitionViewModel,
+    goneToDozingTransitionViewModel: GoneToDozingTransitionViewModel,
+    goneToLockscreenTransitionViewModel: GoneToLockscreenTransitionViewModel,
+    lockscreenToAodTransitionViewModel: LockscreenToAodTransitionViewModel,
+    occludedToAodTransitionViewModel: OccludedToAodTransitionViewModel,
     occludedToDozingTransitionViewModel: OccludedToDozingTransitionViewModel,
+    occludedToLockscreenTransitionViewModel: OccludedToLockscreenTransitionViewModel,
+    primaryBouncerToAodTransitionViewModel: PrimaryBouncerToAodTransitionViewModel,
+    primaryBouncerToDozingTransitionViewModel: PrimaryBouncerToDozingTransitionViewModel,
+    primaryBouncerToLockscreenTransitionViewModel: PrimaryBouncerToLockscreenTransitionViewModel,
 ) {
     val color: Flow<Int> =
         deviceEntryIconViewModel.useBackgroundProtection.flatMapLatest { useBackground ->
@@ -98,7 +97,6 @@
                         goneToLockscreenTransitionViewModel.deviceEntryBackgroundViewAlpha,
                         goneToDozingTransitionViewModel.deviceEntryBackgroundViewAlpha,
                         primaryBouncerToDozingTransitionViewModel.deviceEntryBackgroundViewAlpha,
-                        lockscreenToDozingTransitionViewModel.deviceEntryBackgroundViewAlpha,
                         dozingToLockscreenTransitionViewModel.deviceEntryBackgroundViewAlpha,
                         alternateBouncerToDozingTransitionViewModel.deviceEntryBackgroundViewAlpha,
                         dreamingToAodTransitionViewModel.deviceEntryBackgroundViewAlpha,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt
index 27a1f7a..d3eefca 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt
@@ -45,13 +45,7 @@
             edge = Edge.create(from = LOCKSCREEN, to = DOZING),
         )
 
-    val lockscreenAlpha: Flow<Float> =
-        transitionAnimation.sharedFlow(
-            duration = 250.milliseconds,
-            onStep = { 1 - it },
-            onFinish = { 1f },
-            onCancel = { 1f },
-        )
+    val lockscreenAlpha: Flow<Float> = transitionAnimation.immediatelyTransitionTo(1f)
 
     val shortcutsAlpha: Flow<Float> =
         transitionAnimation.sharedFlow(
@@ -61,18 +55,16 @@
             onCancel = { 1f },
         )
 
-    val deviceEntryBackgroundViewAlpha: Flow<Float> =
-        transitionAnimation.immediatelyTransitionTo(0f)
-
     override val deviceEntryParentViewAlpha: Flow<Float> =
         deviceEntryUdfpsInteractor.isUdfpsEnrolledAndEnabled.flatMapLatest {
             isUdfpsEnrolledAndEnabled ->
-            transitionAnimation.immediatelyTransitionTo(
-                if (isUdfpsEnrolledAndEnabled) {
-                    1f
-                } else {
-                    0f
-                }
-            )
+            if (isUdfpsEnrolledAndEnabled) {
+                transitionAnimation.immediatelyTransitionTo(1f)
+            } else {
+                transitionAnimation.sharedFlow(
+                    duration = 250.milliseconds,
+                    onStep = { 1f - it },
+                )
+            }
         }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneActionsViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt
index 2819e61..dd47678 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt
@@ -28,7 +28,7 @@
 import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade
-import com.android.systemui.scene.ui.viewmodel.SceneActionsViewModel
+import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.util.kotlin.filterValuesNotNull
@@ -40,13 +40,13 @@
 import kotlinx.coroutines.flow.flowOf
 
 /** Models UI state and handles user input for the lockscreen scene. */
-class LockscreenSceneActionsViewModel
+class LockscreenUserActionsViewModel
 @AssistedInject
 constructor(
     private val deviceEntryInteractor: DeviceEntryInteractor,
     private val communalInteractor: CommunalInteractor,
     private val shadeInteractor: ShadeInteractor,
-) : SceneActionsViewModel() {
+) : UserActionsViewModel() {
 
     override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
         shadeInteractor.isShadeTouchable
@@ -119,6 +119,6 @@
 
     @AssistedFactory
     interface Factory {
-        fun create(): LockscreenSceneActionsViewModel
+        fun create(): LockscreenUserActionsViewModel
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
index a65243d..d4af1b5 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
@@ -29,9 +29,8 @@
      * Check whether media control actions should be based on PlaybackState instead of notification
      */
     fun areMediaSessionActionsEnabled(packageName: String, user: UserHandle): Boolean {
-        val enabled = StatusBarManager.useMediaSessionActionsForApp(packageName, user)
         // Allow global override with flag
-        return enabled || featureFlags.isEnabled(Flags.MEDIA_SESSION_ACTIONS)
+        return StatusBarManager.useMediaSessionActionsForApp(packageName, user)
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayActionsViewModel.kt
index 6ef83e2..b6868c1 100644
--- a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayActionsViewModel.kt
@@ -21,13 +21,13 @@
 import com.android.compose.animation.scene.UserAction
 import com.android.compose.animation.scene.UserActionResult
 import com.android.systemui.scene.shared.model.Overlays
-import com.android.systemui.scene.ui.viewmodel.SceneActionsViewModel
+import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 
 /** Models the UI state for the user actions for navigating to other scenes or overlays. */
 class NotificationsShadeOverlayActionsViewModel @AssistedInject constructor() :
-    SceneActionsViewModel() {
+    UserActionsViewModel() {
 
     override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
         setActions(
diff --git a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeUserActionsViewModel.kt
similarity index 85%
rename from packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneActionsViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeUserActionsViewModel.kt
index 572a0ca..a5c07bc 100644
--- a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeUserActionsViewModel.kt
@@ -21,15 +21,15 @@
 import com.android.compose.animation.scene.UserAction
 import com.android.compose.animation.scene.UserActionResult
 import com.android.systemui.scene.shared.model.SceneFamilies
-import com.android.systemui.scene.ui.viewmodel.SceneActionsViewModel
+import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 
 /**
  * Models the UI state for the user actions that the user can perform to navigate to other scenes.
  */
-class NotificationsShadeSceneActionsViewModel @AssistedInject constructor() :
-    SceneActionsViewModel() {
+class NotificationsShadeUserActionsViewModel @AssistedInject constructor() :
+    UserActionsViewModel() {
 
     override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
         setActions(
@@ -42,6 +42,6 @@
 
     @AssistedFactory
     interface Factory {
-        fun create(): NotificationsShadeSceneActionsViewModel
+        fun create(): NotificationsShadeUserActionsViewModel
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneContentViewModel.kt
index a264f51..f77386d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneContentViewModel.kt
@@ -39,7 +39,7 @@
 /**
  * Models UI state needed for rendering the content of the quick settings scene.
  *
- * Different from [QuickSettingsSceneActionsViewModel] that models the UI state needed to figure out
+ * Different from [QuickSettingsUserActionsViewModel] that models the UI state needed to figure out
  * which user actions can trigger navigation to other scenes.
  */
 class QuickSettingsSceneContentViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayActionsViewModel.kt
index 9538392..61c4c8c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayActionsViewModel.kt
@@ -21,13 +21,13 @@
 import com.android.compose.animation.scene.UserAction
 import com.android.compose.animation.scene.UserActionResult
 import com.android.systemui.scene.shared.model.Overlays
-import com.android.systemui.scene.ui.viewmodel.SceneActionsViewModel
+import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 
 /** Models the UI state for the user actions for navigating to other scenes or overlays. */
 class QuickSettingsShadeOverlayActionsViewModel @AssistedInject constructor() :
-    SceneActionsViewModel() {
+    UserActionsViewModel() {
 
     override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
         setActions(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneContentViewModel.kt
index 5185828..d01b33b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneContentViewModel.kt
@@ -22,7 +22,7 @@
 /**
  * Models UI state used to render the content of the quick settings shade scene.
  *
- * Different from [QuickSettingsShadeSceneActionsViewModel], which only models user actions that can
+ * Different from [QuickSettingsShadeUserActionsViewModel], which only models user actions that can
  * be performed to navigate to other scenes.
  */
 class QuickSettingsShadeSceneContentViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeUserActionsViewModel.kt
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneActionsViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeUserActionsViewModel.kt
index 9690aab..d3dc302 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeUserActionsViewModel.kt
@@ -21,7 +21,7 @@
 import com.android.compose.animation.scene.UserAction
 import com.android.compose.animation.scene.UserActionResult
 import com.android.systemui.scene.shared.model.SceneFamilies
-import com.android.systemui.scene.ui.viewmodel.SceneActionsViewModel
+import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import kotlinx.coroutines.flow.map
@@ -32,11 +32,11 @@
  * Different from the [QuickSettingsShadeSceneContentViewModel] which models the _content_ of the
  * scene.
  */
-class QuickSettingsShadeSceneActionsViewModel
+class QuickSettingsShadeUserActionsViewModel
 @AssistedInject
 constructor(
     val quickSettingsContainerViewModel: QuickSettingsContainerViewModel,
-) : SceneActionsViewModel() {
+) : UserActionsViewModel() {
 
     override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
         quickSettingsContainerViewModel.editModeViewModel.isEditing
@@ -53,6 +53,6 @@
 
     @AssistedFactory
     interface Factory {
-        fun create(): QuickSettingsShadeSceneActionsViewModel
+        fun create(): QuickSettingsShadeUserActionsViewModel
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsUserActionsViewModel.kt
similarity index 94%
rename from packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneActionsViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsUserActionsViewModel.kt
index 2bb5dc66..54e5cac 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsUserActionsViewModel.kt
@@ -27,7 +27,7 @@
 import com.android.systemui.scene.domain.interactor.SceneBackInteractor
 import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
-import com.android.systemui.scene.ui.viewmodel.SceneActionsViewModel
+import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import kotlinx.coroutines.flow.Flow
@@ -42,12 +42,12 @@
  * Different from [QuickSettingsSceneContentViewModel] that models UI state needed for rendering the
  * content of the quick settings scene.
  */
-class QuickSettingsSceneActionsViewModel
+class QuickSettingsUserActionsViewModel
 @AssistedInject
 constructor(
     private val qsSceneAdapter: QSSceneAdapter,
     sceneBackInteractor: SceneBackInteractor,
-) : SceneActionsViewModel() {
+) : UserActionsViewModel() {
 
     private val backScene: Flow<SceneKey> =
         sceneBackInteractor.backScene
@@ -82,6 +82,6 @@
 
     @AssistedFactory
     interface Factory {
-        fun create(): QuickSettingsSceneActionsViewModel
+        fun create(): QuickSettingsUserActionsViewModel
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scenes.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scenes.kt
index fcf6288..115d664 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scenes.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scenes.kt
@@ -72,9 +72,7 @@
      * and one for quick settings, [NotificationsShade] and [QuickSettingsShade] scenes are used
      * respectively.
      */
-    @Deprecated("The quick settings shade scene has been replaced by an overlay")
-    @JvmField
-    val QuickSettings = SceneKey("quick_settings")
+    @JvmField val QuickSettings = SceneKey("quick_settings")
 
     /**
      * The quick settings shade scene shows the quick setting tiles as an overlay UI.
@@ -87,7 +85,9 @@
      * large screens or unfolded foldables, where notifications and quick settings are shown
      * side-by-side in their own columns).
      */
-    @JvmField val QuickSettingsShade = SceneKey("quick_settings_shade")
+    @Deprecated("The quick settings shade scene has been replaced by an overlay")
+    @JvmField
+    val QuickSettingsShade = SceneKey("quick_settings_shade")
 
     /**
      * The shade is the scene that shows a scrollable list of notifications and the minimized
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneSceneActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModel.kt
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneSceneActionsViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModel.kt
index 7b0e7f4..ea4122a 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneSceneActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModel.kt
@@ -29,11 +29,11 @@
 import dagger.assisted.AssistedInject
 import kotlinx.coroutines.flow.map
 
-class GoneSceneActionsViewModel
+class GoneUserActionsViewModel
 @AssistedInject
 constructor(
     private val shadeInteractor: ShadeInteractor,
-) : SceneActionsViewModel() {
+) : UserActionsViewModel() {
 
     override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
         shadeInteractor.shadeMode
@@ -69,6 +69,6 @@
 
     @AssistedFactory
     interface Factory {
-        fun create(): GoneSceneActionsViewModel
+        fun create(): GoneUserActionsViewModel
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/UserActionsViewModel.kt
similarity index 91%
rename from packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneActionsViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/UserActionsViewModel.kt
index 0766130..57628d0 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/UserActionsViewModel.kt
@@ -25,15 +25,13 @@
 import kotlinx.coroutines.flow.asStateFlow
 
 /**
- * Base class for view-models that need to keep a map of scene actions (also known as "destination
- * scenes") up-to-date.
+ * Base class for view-models that need to keep a map of user actions up-to-date.
  *
  * Subclasses need only to override [hydrateActions], suspending forever if they need; they don't
  * need to worry about resetting the value of [actions] when the view-model is deactivated/canceled,
  * this base class takes care of it.
  */
-// TODO(b/363206563): Rename to UserActionsViewModel.
-abstract class SceneActionsViewModel : ExclusiveActivatable() {
+abstract class UserActionsViewModel : ExclusiveActivatable() {
 
     private val _actions = MutableStateFlow<Map<UserAction, UserActionResult>>(emptyMap())
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
index 3bb494b..7fa9926 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
@@ -96,7 +96,7 @@
     private val lockscreenSmartspaceController: LockscreenSmartspaceController,
     @CommunalTouchLog logBuffer: LogBuffer,
 ) : LifecycleOwner {
-    private val logger = Logger(logBuffer, "GlanceableHubContainerController")
+    private val logger = Logger(logBuffer, TAG)
 
     private class CommunalWrapper(context: Context) : FrameLayout(context) {
         private val consumers: MutableSet<Consumer<Boolean>> = ArraySet()
@@ -301,7 +301,7 @@
 
         if (touchMonitor == null) {
             touchMonitor =
-                ambientTouchComponentFactory.create(this, HashSet()).getTouchMonitor().apply {
+                ambientTouchComponentFactory.create(this, HashSet(), TAG).getTouchMonitor().apply {
                     init()
                 }
         }
@@ -508,6 +508,11 @@
     fun onTouchEvent(ev: MotionEvent): Boolean {
         SceneContainerFlag.assertInLegacyMode()
 
+        if (communalContainerView == null) {
+            // Return early so we don't log unnecessarily and fill up our LogBuffer.
+            return false
+        }
+
         // In the case that we are handling full swipes on the lockscreen, are on the lockscreen,
         // and the touch is within the horizontal notification band on the screen, do not process
         // the touch.
@@ -528,7 +533,7 @@
             return false
         }
 
-        return communalContainerView?.let { handleTouchEventOnCommunalView(ev) } ?: false
+        return handleTouchEventOnCommunalView(ev)
     }
 
     private fun handleTouchEventOnCommunalView(ev: MotionEvent): Boolean {
@@ -630,4 +635,8 @@
 
     override val lifecycle: Lifecycle
         get() = lifecycleRegistry
+
+    companion object {
+        private const val TAG = "GlanceableHubContainer"
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModel.kt
index 7c70759..ce4c081 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModel.kt
@@ -43,7 +43,7 @@
 /**
  * Models UI state used to render the content of the shade scene.
  *
- * Different from [ShadeSceneActionsViewModel], which only models user actions that can be performed
+ * Different from [ShadeUserActionsViewModel], which only models user actions that can be performed
  * to navigate to other scenes.
  */
 class ShadeSceneContentViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModel.kt
similarity index 93%
rename from packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneActionsViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModel.kt
index ab71913..f8a850a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModel.kt
@@ -24,7 +24,7 @@
 import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade
-import com.android.systemui.scene.ui.viewmodel.SceneActionsViewModel
+import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import dagger.assisted.AssistedFactory
@@ -36,12 +36,12 @@
  *
  * Different from the [ShadeSceneContentViewModel] which models the _content_ of the scene.
  */
-class ShadeSceneActionsViewModel
+class ShadeUserActionsViewModel
 @AssistedInject
 constructor(
     private val qsSceneAdapter: QSSceneAdapter,
     private val shadeInteractor: ShadeInteractor,
-) : SceneActionsViewModel() {
+) : UserActionsViewModel() {
 
     override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
         combine(
@@ -71,6 +71,6 @@
 
     @AssistedFactory
     interface Factory {
-        fun create(): ShadeSceneActionsViewModel
+        fun create(): ShadeUserActionsViewModel
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/config/BcSmartspaceConfigProvider.kt b/packages/SystemUI/src/com/android/systemui/smartspace/config/BcSmartspaceConfigProvider.kt
index 922560f..0e1bf72 100644
--- a/packages/SystemUI/src/com/android/systemui/smartspace/config/BcSmartspaceConfigProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/config/BcSmartspaceConfigProvider.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.smartspace.config
 
+import com.android.systemui.Flags.smartspaceViewpager2
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.plugins.BcSmartspaceConfigPlugin
 
@@ -23,4 +24,7 @@
     BcSmartspaceConfigPlugin {
     override val isDefaultDateWeatherDisabled: Boolean
         get() = true
+
+    override val isViewPager2Enabled: Boolean
+        get() = smartspaceViewpager2()
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt
new file mode 100644
index 0000000..3b1e565
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.chips.ui.binder
+
+import android.annotation.IdRes
+import android.content.res.ColorStateList
+import android.graphics.drawable.GradientDrawable
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import android.widget.ImageView
+import android.widget.TextView
+import com.android.systemui.common.ui.binder.IconViewBinder
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.chips.ron.shared.StatusBarRonChips
+import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
+import com.android.systemui.statusbar.chips.ui.view.ChipChronometer
+
+/** Binder for ongoing activity chip views. */
+object OngoingActivityChipBinder {
+    /** Binds the given [chipModel] data to the given [chipView]. */
+    fun bind(chipModel: OngoingActivityChipModel, chipView: View) {
+        val chipContext = chipView.context
+        val chipDefaultIconView: ImageView =
+            chipView.requireViewById(R.id.ongoing_activity_chip_icon)
+        val chipTimeView: ChipChronometer =
+            chipView.requireViewById(R.id.ongoing_activity_chip_time)
+        val chipTextView: TextView = chipView.requireViewById(R.id.ongoing_activity_chip_text)
+        val chipBackgroundView: ChipBackgroundContainer =
+            chipView.requireViewById(R.id.ongoing_activity_chip_background)
+
+        when (chipModel) {
+            is OngoingActivityChipModel.Shown -> {
+                // Data
+                setChipIcon(chipModel, chipBackgroundView, chipDefaultIconView)
+                setChipMainContent(chipModel, chipTextView, chipTimeView)
+                chipView.setOnClickListener(chipModel.onClickListener)
+                updateChipPadding(
+                    chipModel,
+                    chipBackgroundView,
+                    chipTextView,
+                    chipTimeView,
+                )
+
+                // Accessibility
+                setChipAccessibility(chipModel, chipView, chipBackgroundView)
+
+                // Colors
+                val textColor = chipModel.colors.text(chipContext)
+                chipTimeView.setTextColor(textColor)
+                chipTextView.setTextColor(textColor)
+                (chipBackgroundView.background as GradientDrawable).color =
+                    chipModel.colors.background(chipContext)
+            }
+            is OngoingActivityChipModel.Hidden -> {
+                // The Chronometer should be stopped to prevent leaks -- see b/192243808 and
+                // [Chronometer.start].
+                chipTimeView.stop()
+            }
+        }
+    }
+
+    private fun setChipIcon(
+        chipModel: OngoingActivityChipModel.Shown,
+        backgroundView: ChipBackgroundContainer,
+        defaultIconView: ImageView,
+    ) {
+        // Always remove any previously set custom icon. If we have a new custom icon, we'll re-add
+        // it.
+        backgroundView.removeView(backgroundView.getCustomIconView())
+
+        val iconTint = chipModel.colors.text(defaultIconView.context)
+
+        when (val icon = chipModel.icon) {
+            null -> {
+                defaultIconView.visibility = View.GONE
+            }
+            is OngoingActivityChipModel.ChipIcon.SingleColorIcon -> {
+                IconViewBinder.bind(icon.impl, defaultIconView)
+                defaultIconView.visibility = View.VISIBLE
+                defaultIconView.tintView(iconTint)
+            }
+            is OngoingActivityChipModel.ChipIcon.FullColorAppIcon -> {
+                StatusBarRonChips.assertInNewMode()
+                IconViewBinder.bind(icon.impl, defaultIconView)
+                defaultIconView.visibility = View.VISIBLE
+                defaultIconView.untintView()
+            }
+            is OngoingActivityChipModel.ChipIcon.StatusBarView -> {
+                // Hide the default icon since we'll show this custom icon instead.
+                defaultIconView.visibility = View.GONE
+
+                // Add the new custom icon:
+                // 1. Set up the right visual params.
+                val iconView = icon.impl
+                with(iconView) {
+                    id = CUSTOM_ICON_VIEW_ID
+                    // TODO(b/354930838): Update the content description to not include "phone" and
+                    // maybe include the app name.
+                    contentDescription =
+                        context.resources.getString(R.string.ongoing_phone_call_content_description)
+                    tintView(iconTint)
+                }
+
+                // 2. If we just reinflated the view, we may need to detach the icon view from the
+                // old chip before we reattach it to the new one.
+                // See also: NotificationIconContainerViewBinder#bindIcons.
+                val currentParent = iconView.parent as? ViewGroup
+                if (currentParent != null && currentParent != backgroundView) {
+                    currentParent.removeView(iconView)
+                    currentParent.removeTransientView(iconView)
+                }
+
+                // 3: Add the icon as the starting view.
+                backgroundView.addView(
+                    iconView,
+                    /* index= */ 0,
+                    generateCustomIconLayoutParams(iconView),
+                )
+            }
+        }
+    }
+
+    private fun View.getCustomIconView(): StatusBarIconView? {
+        return this.findViewById(CUSTOM_ICON_VIEW_ID)
+    }
+
+    private fun ImageView.tintView(color: Int) {
+        this.imageTintList = ColorStateList.valueOf(color)
+    }
+
+    private fun ImageView.untintView() {
+        this.imageTintList = null
+    }
+
+    private fun generateCustomIconLayoutParams(iconView: ImageView): FrameLayout.LayoutParams {
+        val customIconSize =
+            iconView.context.resources.getDimensionPixelSize(
+                R.dimen.ongoing_activity_chip_embedded_padding_icon_size
+            )
+        return FrameLayout.LayoutParams(customIconSize, customIconSize)
+    }
+
+    private fun setChipMainContent(
+        chipModel: OngoingActivityChipModel.Shown,
+        chipTextView: TextView,
+        chipTimeView: ChipChronometer,
+    ) {
+        when (chipModel) {
+            is OngoingActivityChipModel.Shown.Countdown -> {
+                chipTextView.text = chipModel.secondsUntilStarted.toString()
+                chipTextView.visibility = View.VISIBLE
+
+                chipTimeView.hide()
+            }
+            is OngoingActivityChipModel.Shown.Text -> {
+                chipTextView.text = chipModel.text
+                chipTextView.visibility = View.VISIBLE
+
+                chipTimeView.hide()
+            }
+            is OngoingActivityChipModel.Shown.Timer -> {
+                ChipChronometerBinder.bind(chipModel.startTimeMs, chipTimeView)
+                chipTimeView.visibility = View.VISIBLE
+
+                chipTextView.visibility = View.GONE
+            }
+            is OngoingActivityChipModel.Shown.IconOnly -> {
+                chipTextView.visibility = View.GONE
+                chipTimeView.hide()
+            }
+        }
+    }
+
+    private fun ChipChronometer.hide() {
+        // The Chronometer should be stopped to prevent leaks -- see b/192243808 and
+        // [Chronometer.start].
+        this.stop()
+        this.visibility = View.GONE
+    }
+
+    private fun updateChipPadding(
+        chipModel: OngoingActivityChipModel.Shown,
+        backgroundView: View,
+        chipTextView: TextView,
+        chipTimeView: ChipChronometer,
+    ) {
+        if (chipModel.icon != null) {
+            if (chipModel.icon is OngoingActivityChipModel.ChipIcon.StatusBarView) {
+                // If the icon is a custom [StatusBarIconView], then it should've come from
+                // `Notification.smallIcon`, which is required to embed its own paddings. We need to
+                // adjust the other paddings to make everything look good :)
+                backgroundView.setBackgroundPaddingForEmbeddedPaddingIcon()
+                chipTextView.setTextPaddingForEmbeddedPaddingIcon()
+                chipTimeView.setTextPaddingForEmbeddedPaddingIcon()
+            } else {
+                backgroundView.setBackgroundPaddingForNormalIcon()
+                chipTextView.setTextPaddingForNormalIcon()
+                chipTimeView.setTextPaddingForNormalIcon()
+            }
+        } else {
+            backgroundView.setBackgroundPaddingForNoIcon()
+            chipTextView.setTextPaddingForNoIcon()
+            chipTimeView.setTextPaddingForNoIcon()
+        }
+    }
+
+    private fun View.setTextPaddingForEmbeddedPaddingIcon() {
+        val newPaddingEnd =
+            context.resources.getDimensionPixelSize(
+                R.dimen.ongoing_activity_chip_text_end_padding_for_embedded_padding_icon
+            )
+        setPaddingRelative(
+            // The icon should embed enough padding between the icon and time view.
+            /* start= */ 0,
+            this.paddingTop,
+            newPaddingEnd,
+            this.paddingBottom,
+        )
+    }
+
+    private fun View.setTextPaddingForNormalIcon() {
+        this.setPaddingRelative(
+            this.context.resources.getDimensionPixelSize(
+                R.dimen.ongoing_activity_chip_icon_text_padding
+            ),
+            paddingTop,
+            // The background view will contain the right end padding.
+            /* end= */ 0,
+            paddingBottom,
+        )
+    }
+
+    private fun View.setTextPaddingForNoIcon() {
+        // The background view will have even start & end paddings, so we don't want the text view
+        // to add any additional padding.
+        this.setPaddingRelative(/* start= */ 0, paddingTop, /* end= */ 0, paddingBottom)
+    }
+
+    private fun View.setBackgroundPaddingForEmbeddedPaddingIcon() {
+        val sidePadding =
+            context.resources.getDimensionPixelSize(
+                R.dimen.ongoing_activity_chip_side_padding_for_embedded_padding_icon
+            )
+        setPaddingRelative(
+            sidePadding,
+            paddingTop,
+            sidePadding,
+            paddingBottom,
+        )
+    }
+
+    private fun View.setBackgroundPaddingForNormalIcon() {
+        val sidePadding =
+            context.resources.getDimensionPixelSize(R.dimen.ongoing_activity_chip_side_padding)
+        setPaddingRelative(
+            sidePadding,
+            paddingTop,
+            sidePadding,
+            paddingBottom,
+        )
+    }
+
+    private fun View.setBackgroundPaddingForNoIcon() {
+        // The padding for the normal icon is also appropriate for no icon.
+        setBackgroundPaddingForNormalIcon()
+    }
+
+    private fun setChipAccessibility(
+        chipModel: OngoingActivityChipModel.Shown,
+        chipView: View,
+        chipBackgroundView: View,
+    ) {
+        when (chipModel) {
+            is OngoingActivityChipModel.Shown.Countdown -> {
+                // Set as assertive so talkback will announce the countdown
+                chipView.accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE
+            }
+            is OngoingActivityChipModel.Shown.Timer,
+            is OngoingActivityChipModel.Shown.Text,
+            is OngoingActivityChipModel.Shown.IconOnly -> {
+                chipView.accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_NONE
+            }
+        }
+        // Clickable chips need to be a minimum size for accessibility purposes, but let
+        // non-clickable chips be smaller.
+        if (chipModel.onClickListener != null) {
+            chipBackgroundView.minimumWidth =
+                chipBackgroundView.context.resources.getDimensionPixelSize(
+                    R.dimen.min_clickable_item_size
+                )
+        } else {
+            chipBackgroundView.minimumWidth = 0
+        }
+    }
+
+    @IdRes private val CUSTOM_ICON_VIEW_ID = R.id.ongoing_activity_chip_custom_icon
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt
index 04c4516..199eb06 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt
@@ -151,13 +151,13 @@
         }
 
     /**
-     * A flow modeling the chip that should be shown in the status bar after accounting for possibly
-     * multiple ongoing activities and animation requirements.
+     * A flow modeling the primary chip that should be shown in the status bar after accounting for
+     * possibly multiple ongoing activities and animation requirements.
      *
      * [com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment] is responsible for
      * actually displaying the chip.
      */
-    val chip: StateFlow<OngoingActivityChipModel> =
+    val primaryChip: StateFlow<OngoingActivityChipModel> =
         internalChip
             .pairwise(initialValue = DEFAULT_INTERNAL_HIDDEN_MODEL)
             .map { (old, new) ->
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
index 3a2f95e..6d0148a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
@@ -22,7 +22,7 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.systemui.Dumpable;
-import com.android.systemui.communal.domain.interactor.CommunalInteractor;
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dump.DumpManager;
@@ -32,6 +32,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractor;
+import com.android.systemui.shade.domain.interactor.ShadeInteractor;
 import com.android.systemui.statusbar.notification.VisibilityLocationProvider;
 import com.android.systemui.statusbar.notification.collection.GroupEntry;
 import com.android.systemui.statusbar.notification.collection.ListEntry;
@@ -43,6 +44,7 @@
 import com.android.systemui.statusbar.notification.shared.NotificationMinimalismPrototype;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.util.concurrency.DelayableExecutor;
+import com.android.systemui.util.kotlin.BooleanFlowOperators;
 import com.android.systemui.util.kotlin.JavaAdapter;
 
 import java.io.PrintWriter;
@@ -70,7 +72,8 @@
     private final VisibilityLocationProvider mVisibilityLocationProvider;
     private final VisualStabilityProvider mVisualStabilityProvider;
     private final WakefulnessLifecycle mWakefulnessLifecycle;
-    private final CommunalInteractor mCommunalInteractor;
+    private final CommunalSceneInteractor mCommunalSceneInteractor;
+    private final ShadeInteractor mShadeInteractor;
     private final KeyguardTransitionInteractor mKeyguardTransitionInteractor;
     private final VisualStabilityCoordinatorLogger mLogger;
 
@@ -110,7 +113,8 @@
             VisibilityLocationProvider visibilityLocationProvider,
             VisualStabilityProvider visualStabilityProvider,
             WakefulnessLifecycle wakefulnessLifecycle,
-            CommunalInteractor communalInteractor,
+            CommunalSceneInteractor communalSceneInteractor,
+            ShadeInteractor shadeInteractor,
             KeyguardTransitionInteractor keyguardTransitionInteractor,
             VisualStabilityCoordinatorLogger logger) {
         mHeadsUpManager = headsUpManager;
@@ -122,7 +126,8 @@
         mWakefulnessLifecycle = wakefulnessLifecycle;
         mStatusBarStateController = statusBarStateController;
         mDelayableExecutor = delayableExecutor;
-        mCommunalInteractor = communalInteractor;
+        mCommunalSceneInteractor = communalSceneInteractor;
+        mShadeInteractor = shadeInteractor;
         mKeyguardTransitionInteractor = keyguardTransitionInteractor;
         mLogger = logger;
 
@@ -141,7 +146,11 @@
                 this::onShadeOrQsClosingChanged);
         mJavaAdapter.alwaysCollectFlow(mShadeAnimationInteractor.isLaunchingActivity(),
                 this::onLaunchingActivityChanged);
-        mJavaAdapter.alwaysCollectFlow(mCommunalInteractor.isIdleOnCommunal(),
+        mJavaAdapter.alwaysCollectFlow(
+                BooleanFlowOperators.INSTANCE.allOf(
+                        mCommunalSceneInteractor.isIdleOnCommunal(),
+                        BooleanFlowOperators.INSTANCE.not(mShadeInteractor.isAnyFullyExpanded())
+                ),
                 this::onCommunalShowingChanged);
 
         if (SceneContainerFlag.isEnabled()) {
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 b9628e9..48e69893 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
@@ -3710,7 +3710,7 @@
         if (!isScrollingEnabled()) {
             return false;
         }
-        if (isInsideQsHeader(ev) && !mIsBeingDragged) {
+        if (!isInScrollableRegion(ev) && !mIsBeingDragged) {
             return false;
         }
         mForcedScroll = null;
@@ -3878,11 +3878,26 @@
         return mFlingAfterUpEvent;
     }
 
-    protected boolean isInsideQsHeader(MotionEvent ev) {
-        if (SceneContainerFlag.isEnabled()) {
-            return ev.getY() < mAmbientState.getStackTop();
+    /** Is this touch event inside the scrollable region? */
+    @VisibleForTesting
+    boolean isInScrollableRegion(MotionEvent ev) {
+        if (!SceneContainerFlag.isEnabled()) {
+            return !isInsideQsHeader(ev);
+        }
+        ShadeScrimShape shape = mScrollViewFields.getScrimClippingShape();
+        if (shape == null) {
+            return true; // When there is no scrim, consider this event scrollable.
         }
 
+        ShadeScrimBounds bounds = shape.getBounds();
+        return ev.getX() >= bounds.getLeft()
+                && ev.getX() <= bounds.getRight()
+                && ev.getY() >= bounds.getTop()
+                && ev.getY() <= bounds.getBottom();
+    }
+
+    protected boolean isInsideQsHeader(MotionEvent ev) {
+        SceneContainerFlag.assertInLegacyMode();
         if (QSComposeFragment.isEnabled()) {
             if (mQSHeaderBoundsProvider == null) {
                 return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index c3da7fc..178c318 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -435,13 +435,14 @@
 
     /** Should only be called from {@link KeyguardStatusBarViewController}. */
     void onOverlayChanged() {
-        int theme = Utils.getThemeAttr(mContext, com.android.internal.R.attr.textAppearanceSmall);
-        mCarrierLabel.setTextAppearance(theme);
+        final int carrierTheme = R.style.TextAppearance_StatusBar_Clock;
+        mCarrierLabel.setTextAppearance(carrierTheme);
         mBatteryView.updatePercentView();
 
+        final int userSwitcherTheme = R.style.TextAppearance_StatusBar_UserChip;
         TextView userSwitcherName = mUserSwitcherContainer.findViewById(R.id.current_user_name);
         if (userSwitcherName != null) {
-            userSwitcherName.setTextAppearance(theme);
+            userSwitcherName.setTextAppearance(userSwitcherTheme);
         }
     }
 
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 5be4ba2..4a0fdee 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
@@ -121,7 +121,7 @@
     private MultiSourceMinAlphaController mEndSideAlphaController;
     private LinearLayout mEndSideContent;
     private View mClockView;
-    private View mOngoingActivityChip;
+    private View mPrimaryOngoingActivityChip;
     private View mNotificationIconAreaInner;
     // Visibilities come in from external system callers via disable flags, but we also sometimes
     // modify the visibilities internally. We need to store both so that we don't accidentally
@@ -354,7 +354,7 @@
         mEndSideContent = mStatusBar.findViewById(R.id.status_bar_end_side_content);
         mEndSideAlphaController = new MultiSourceMinAlphaController(mEndSideContent);
         mClockView = mStatusBar.findViewById(R.id.clock);
-        mOngoingActivityChip = mStatusBar.findViewById(R.id.ongoing_activity_chip);
+        mPrimaryOngoingActivityChip = mStatusBar.findViewById(R.id.ongoing_activity_chip_primary);
         showEndSideContent(false);
         showClock(false);
         initOperatorName();
@@ -636,9 +636,9 @@
         // icons so if the icons are disabled then the activity chip should be, too.)
         boolean showOngoingActivityChip = hasOngoingActivity && !disableNotifications;
         if (showOngoingActivityChip) {
-            showOngoingActivityChip(animate);
+            showPrimaryOngoingActivityChip(animate);
         } else {
-            hideOngoingActivityChip(animate);
+            hidePrimaryOngoingActivityChip(animate);
         }
     }
 
@@ -729,20 +729,20 @@
         animateShow(mClockView, animate);
     }
 
-    /** Hides the ongoing activity chip. */
-    private void hideOngoingActivityChip(boolean animate) {
-        animateHiddenState(mOngoingActivityChip, View.GONE, animate);
+    /** Hides the primary ongoing activity chip. */
+    private void hidePrimaryOngoingActivityChip(boolean animate) {
+        animateHiddenState(mPrimaryOngoingActivityChip, View.GONE, animate);
     }
 
     /**
-     * Displays the ongoing activity chip.
+     * Displays the primary ongoing activity chip.
      *
      * If Flags.statusBarScreenSharingChips is disabled, this chip will only ever contain the
      * ongoing call information, If that flag is enabled, it will support different kinds of ongoing
      * activities. See b/332662551.
      */
-    private void showOngoingActivityChip(boolean animate) {
-        animateShow(mOngoingActivityChip, animate);
+    private void showPrimaryOngoingActivityChip(boolean animate) {
+        animateShow(mPrimaryOngoingActivityChip, animate);
     }
 
     /**
@@ -850,7 +850,7 @@
 
     private void initOngoingCallChip() {
         mOngoingCallController.addCallback(mOngoingCallListener);
-        mOngoingCallController.setChipView(mOngoingActivityChip);
+        mOngoingCallController.setChipView(mPrimaryOngoingActivityChip);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
index c24d694..87d0e64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
@@ -18,28 +18,16 @@
 
 import android.animation.Animator
 import android.animation.AnimatorListenerAdapter
-import android.annotation.IdRes
-import android.content.res.ColorStateList
-import android.graphics.drawable.GradientDrawable
 import android.view.View
-import android.view.ViewGroup
-import android.widget.FrameLayout
-import android.widget.ImageView
-import android.widget.TextView
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.systemui.Flags
-import com.android.systemui.common.ui.binder.IconViewBinder
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.res.R
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.statusbar.StatusBarIconView
-import com.android.systemui.statusbar.chips.ron.shared.StatusBarRonChips
-import com.android.systemui.statusbar.chips.ui.binder.ChipChronometerBinder
+import com.android.systemui.statusbar.chips.ui.binder.OngoingActivityChipBinder
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
-import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
-import com.android.systemui.statusbar.chips.ui.view.ChipChronometer
 import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
 import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel
 import javax.inject.Inject
@@ -93,58 +81,22 @@
                 }
 
                 if (Flags.statusBarScreenSharingChips()) {
-                    val chipView: View = view.requireViewById(R.id.ongoing_activity_chip)
-                    val chipContext = chipView.context
-                    val chipDefaultIconView: ImageView =
-                        chipView.requireViewById(R.id.ongoing_activity_chip_icon)
-                    val chipTimeView: ChipChronometer =
-                        chipView.requireViewById(R.id.ongoing_activity_chip_time)
-                    val chipTextView: TextView =
-                        chipView.requireViewById(R.id.ongoing_activity_chip_text)
-                    val chipBackgroundView =
-                        chipView.requireViewById<ChipBackgroundContainer>(
-                            R.id.ongoing_activity_chip_background
-                        )
+                    val primaryChipView: View =
+                        view.requireViewById(R.id.ongoing_activity_chip_primary)
                     launch {
-                        viewModel.ongoingActivityChip.collect { chipModel ->
-                            when (chipModel) {
-                                is OngoingActivityChipModel.Shown -> {
-                                    // Data
-                                    setChipIcon(chipModel, chipBackgroundView, chipDefaultIconView)
-                                    setChipMainContent(chipModel, chipTextView, chipTimeView)
-                                    chipView.setOnClickListener(chipModel.onClickListener)
-                                    updateChipPadding(
-                                        chipModel,
-                                        chipBackgroundView,
-                                        chipTextView,
-                                        chipTimeView,
-                                    )
-
-                                    // Accessibility
-                                    setChipAccessibility(chipModel, chipView, chipBackgroundView)
-
-                                    // Colors
-                                    val textColor = chipModel.colors.text(chipContext)
-                                    chipTimeView.setTextColor(textColor)
-                                    chipTextView.setTextColor(textColor)
-                                    (chipBackgroundView.background as GradientDrawable).color =
-                                        chipModel.colors.background(chipContext)
-
-                                    // Notify listeners
+                        viewModel.primaryOngoingActivityChip.collect { primaryChipModel ->
+                            OngoingActivityChipBinder.bind(primaryChipModel, primaryChipView)
+                            when (primaryChipModel) {
+                                is OngoingActivityChipModel.Shown ->
                                     listener.onOngoingActivityStatusChanged(
                                         hasOngoingActivity = true,
                                         shouldAnimate = true,
                                     )
-                                }
-                                is OngoingActivityChipModel.Hidden -> {
-                                    // The Chronometer should be stopped to prevent leaks -- see
-                                    // b/192243808 and [Chronometer.start].
-                                    chipTimeView.stop()
+                                is OngoingActivityChipModel.Hidden ->
                                     listener.onOngoingActivityStatusChanged(
                                         hasOngoingActivity = false,
-                                        shouldAnimate = chipModel.shouldAnimate,
+                                        shouldAnimate = primaryChipModel.shouldAnimate,
                                     )
-                                }
                             }
                         }
                     }
@@ -161,240 +113,6 @@
         }
     }
 
-    private fun setChipIcon(
-        chipModel: OngoingActivityChipModel.Shown,
-        backgroundView: ChipBackgroundContainer,
-        defaultIconView: ImageView,
-    ) {
-        // Always remove any previously set custom icon. If we have a new custom icon, we'll re-add
-        // it.
-        backgroundView.removeView(backgroundView.getCustomIconView())
-
-        val iconTint = chipModel.colors.text(defaultIconView.context)
-
-        when (val icon = chipModel.icon) {
-            null -> {
-                defaultIconView.visibility = View.GONE
-            }
-            is OngoingActivityChipModel.ChipIcon.SingleColorIcon -> {
-                IconViewBinder.bind(icon.impl, defaultIconView)
-                defaultIconView.visibility = View.VISIBLE
-                defaultIconView.tintView(iconTint)
-            }
-            is OngoingActivityChipModel.ChipIcon.FullColorAppIcon -> {
-                StatusBarRonChips.assertInNewMode()
-                IconViewBinder.bind(icon.impl, defaultIconView)
-                defaultIconView.visibility = View.VISIBLE
-                defaultIconView.untintView()
-            }
-            is OngoingActivityChipModel.ChipIcon.StatusBarView -> {
-                // Hide the default icon since we'll show this custom icon instead.
-                defaultIconView.visibility = View.GONE
-
-                // Add the new custom icon:
-                // 1. Set up the right visual params.
-                val iconView = icon.impl
-                with(iconView) {
-                    id = CUSTOM_ICON_VIEW_ID
-                    // TODO(b/354930838): Update the content description to not include "phone" and
-                    // maybe include the app name.
-                    contentDescription =
-                        context.resources.getString(R.string.ongoing_phone_call_content_description)
-                    tintView(iconTint)
-                }
-
-                // 2. If we just reinflated the view, we may need to detach the icon view from the
-                // old chip before we reattach it to the new one.
-                // See also: NotificationIconContainerViewBinder#bindIcons.
-                val currentParent = iconView.parent as? ViewGroup
-                if (currentParent != null && currentParent != backgroundView) {
-                    currentParent.removeView(iconView)
-                    currentParent.removeTransientView(iconView)
-                }
-
-                // 3: Add the icon as the starting view.
-                backgroundView.addView(
-                    iconView,
-                    /* index= */ 0,
-                    generateCustomIconLayoutParams(iconView),
-                )
-            }
-        }
-    }
-
-    private fun View.getCustomIconView(): StatusBarIconView? {
-        return this.findViewById(CUSTOM_ICON_VIEW_ID)
-    }
-
-    private fun ImageView.tintView(color: Int) {
-        this.imageTintList = ColorStateList.valueOf(color)
-    }
-
-    private fun ImageView.untintView() {
-        this.imageTintList = null
-    }
-
-    private fun generateCustomIconLayoutParams(iconView: ImageView): FrameLayout.LayoutParams {
-        val customIconSize =
-            iconView.context.resources.getDimensionPixelSize(
-                R.dimen.ongoing_activity_chip_embedded_padding_icon_size
-            )
-        return FrameLayout.LayoutParams(customIconSize, customIconSize)
-    }
-
-    private fun setChipMainContent(
-        chipModel: OngoingActivityChipModel.Shown,
-        chipTextView: TextView,
-        chipTimeView: ChipChronometer,
-    ) {
-        when (chipModel) {
-            is OngoingActivityChipModel.Shown.Countdown -> {
-                chipTextView.text = chipModel.secondsUntilStarted.toString()
-                chipTextView.visibility = View.VISIBLE
-
-                chipTimeView.hide()
-            }
-            is OngoingActivityChipModel.Shown.Text -> {
-                chipTextView.text = chipModel.text
-                chipTextView.visibility = View.VISIBLE
-
-                chipTimeView.hide()
-            }
-            is OngoingActivityChipModel.Shown.Timer -> {
-                ChipChronometerBinder.bind(chipModel.startTimeMs, chipTimeView)
-                chipTimeView.visibility = View.VISIBLE
-
-                chipTextView.visibility = View.GONE
-            }
-            is OngoingActivityChipModel.Shown.IconOnly -> {
-                chipTextView.visibility = View.GONE
-                chipTimeView.hide()
-            }
-        }
-    }
-
-    private fun ChipChronometer.hide() {
-        // The Chronometer should be stopped to prevent leaks -- see b/192243808 and
-        // [Chronometer.start].
-        this.stop()
-        this.visibility = View.GONE
-    }
-
-    private fun updateChipPadding(
-        chipModel: OngoingActivityChipModel.Shown,
-        backgroundView: View,
-        chipTextView: TextView,
-        chipTimeView: ChipChronometer,
-    ) {
-        if (chipModel.icon != null) {
-            if (chipModel.icon is OngoingActivityChipModel.ChipIcon.StatusBarView) {
-                // If the icon is a custom [StatusBarIconView], then it should've come from
-                // `Notification.smallIcon`, which is required to embed its own paddings. We need to
-                // adjust the other paddings to make everything look good :)
-                backgroundView.setBackgroundPaddingForEmbeddedPaddingIcon()
-                chipTextView.setTextPaddingForEmbeddedPaddingIcon()
-                chipTimeView.setTextPaddingForEmbeddedPaddingIcon()
-            } else {
-                backgroundView.setBackgroundPaddingForNormalIcon()
-                chipTextView.setTextPaddingForNormalIcon()
-                chipTimeView.setTextPaddingForNormalIcon()
-            }
-        } else {
-            backgroundView.setBackgroundPaddingForNoIcon()
-            chipTextView.setTextPaddingForNoIcon()
-            chipTimeView.setTextPaddingForNoIcon()
-        }
-    }
-
-    private fun View.setTextPaddingForEmbeddedPaddingIcon() {
-        val newPaddingEnd =
-            context.resources.getDimensionPixelSize(
-                R.dimen.ongoing_activity_chip_text_end_padding_for_embedded_padding_icon
-            )
-        setPaddingRelative(
-            // The icon should embed enough padding between the icon and time view.
-            /* start= */ 0,
-            this.paddingTop,
-            newPaddingEnd,
-            this.paddingBottom,
-        )
-    }
-
-    private fun View.setTextPaddingForNormalIcon() {
-        this.setPaddingRelative(
-            this.context.resources.getDimensionPixelSize(
-                R.dimen.ongoing_activity_chip_icon_text_padding
-            ),
-            paddingTop,
-            // The background view will contain the right end padding.
-            /* end= */ 0,
-            paddingBottom,
-        )
-    }
-
-    private fun View.setTextPaddingForNoIcon() {
-        // The background view will have even start & end paddings, so we don't want the text view
-        // to add any additional padding.
-        this.setPaddingRelative(/* start= */ 0, paddingTop, /* end= */ 0, paddingBottom)
-    }
-
-    private fun View.setBackgroundPaddingForEmbeddedPaddingIcon() {
-        val sidePadding =
-            context.resources.getDimensionPixelSize(
-                R.dimen.ongoing_activity_chip_side_padding_for_embedded_padding_icon
-            )
-        setPaddingRelative(
-            sidePadding,
-            paddingTop,
-            sidePadding,
-            paddingBottom,
-        )
-    }
-
-    private fun View.setBackgroundPaddingForNormalIcon() {
-        val sidePadding =
-            context.resources.getDimensionPixelSize(R.dimen.ongoing_activity_chip_side_padding)
-        setPaddingRelative(
-            sidePadding,
-            paddingTop,
-            sidePadding,
-            paddingBottom,
-        )
-    }
-
-    private fun View.setBackgroundPaddingForNoIcon() {
-        // The padding for the normal icon is also appropriate for no icon.
-        setBackgroundPaddingForNormalIcon()
-    }
-
-    private fun setChipAccessibility(
-        chipModel: OngoingActivityChipModel.Shown,
-        chipView: View,
-        chipBackgroundView: View,
-    ) {
-        when (chipModel) {
-            is OngoingActivityChipModel.Shown.Countdown -> {
-                // Set as assertive so talkback will announce the countdown
-                chipView.accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE
-            }
-            is OngoingActivityChipModel.Shown.Timer,
-            is OngoingActivityChipModel.Shown.Text,
-            is OngoingActivityChipModel.Shown.IconOnly -> {
-                chipView.accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_NONE
-            }
-        }
-        // Clickable chips need to be a minimum size for accessibility purposes, but let
-        // non-clickable chips be smaller.
-        if (chipModel.onClickListener != null) {
-            chipBackgroundView.minimumWidth =
-                chipBackgroundView.context.resources.getDimensionPixelSize(
-                    R.dimen.min_clickable_item_size
-                )
-        } else {
-            chipBackgroundView.minimumWidth = 0
-        }
-    }
-
     private fun animateLightsOutView(view: View, visible: Boolean) {
         view.animate().cancel()
 
@@ -424,10 +142,6 @@
             )
             .start()
     }
-
-    companion object {
-        @IdRes private val CUSTOM_ICON_VIEW_ID = R.id.ongoing_activity_chip_custom_icon
-    }
 }
 
 /** Listener for various events that may affect the status bar's visibility. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt
index d6c3834..5474231 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt
@@ -64,8 +64,11 @@
     /** Emits whenever a transition from lockscreen to dream has started. */
     val transitionFromLockscreenToDreamStartedEvent: Flow<Unit>
 
-    /** The ongoing activity chip that should be shown on the left-hand side of the status bar. */
-    val ongoingActivityChip: StateFlow<OngoingActivityChipModel>
+    /**
+     * The ongoing activity chip that should be primarily shown on the left-hand side of the status
+     * bar. If there are multiple ongoing activity chips, this one should take priority.
+     */
+    val primaryOngoingActivityChip: StateFlow<OngoingActivityChipModel>
 
     /**
      * True if the current scene can show the home status bar (aka this status bar), and false if
@@ -108,7 +111,7 @@
             .filter { it.transitionState == TransitionState.STARTED }
             .map {}
 
-    override val ongoingActivityChip = ongoingActivityChipsViewModel.chip
+    override val primaryOngoingActivityChip = ongoingActivityChipsViewModel.primaryChip
 
     override val isHomeStatusBarAllowedByScene: StateFlow<Boolean> =
         combine(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
index 885abca..7df4b2c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
@@ -29,8 +29,6 @@
 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.flags.FeatureFlags
-import com.android.systemui.flags.Flags
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.LogLevel
 import com.android.systemui.log.table.TableLogBuffer
@@ -75,7 +73,6 @@
 class WifiRepositoryImpl
 @Inject
 constructor(
-    featureFlags: FeatureFlags,
     @Application private val scope: CoroutineScope,
     @Main private val mainExecutor: Executor,
     @Background private val bgDispatcher: CoroutineDispatcher,
@@ -90,8 +87,6 @@
             mainExecutor.execute { it.currentState = Lifecycle.State.CREATED }
         }
 
-    private val isInstantTetherEnabled = featureFlags.isEnabled(Flags.INSTANT_TETHER)
-
     private var wifiPickerTracker: WifiPickerTracker? = null
 
     private val wifiPickerTrackerInfo: StateFlow<WifiPickerTrackerInfo> = run {
@@ -109,16 +104,11 @@
                             val connectedEntry = wifiPickerTracker.mergedOrPrimaryConnection
                             logOnWifiEntriesChanged(connectedEntry)
 
+                            val activeNetworks = wifiPickerTracker?.activeWifiEntries ?: emptyList()
                             val secondaryNetworks =
-                                if (featureFlags.isEnabled(Flags.WIFI_SECONDARY_NETWORKS)) {
-                                    val activeNetworks =
-                                        wifiPickerTracker?.activeWifiEntries ?: emptyList()
-                                    activeNetworks
-                                        .filter { it != connectedEntry && !it.isPrimaryNetwork }
-                                        .map { it.toWifiNetworkModel() }
-                                } else {
-                                    emptyList()
-                                }
+                                activeNetworks
+                                    .filter { it != connectedEntry && !it.isPrimaryNetwork }
+                                    .map { it.toWifiNetworkModel() }
 
                             // [WifiPickerTracker.connectedWifiEntry] will return the same instance
                             // but with updated internals. For example, when its validation status
@@ -130,7 +120,8 @@
                             // into our internal model immediately. [toWifiNetworkModel] always
                             // returns a new instance, so the flow is guaranteed to emit.
                             send(
-                                newPrimaryNetwork = connectedEntry?.toPrimaryWifiNetworkModel()
+                                newPrimaryNetwork =
+                                    connectedEntry?.toPrimaryWifiNetworkModel()
                                         ?: WIFI_NETWORK_DEFAULT,
                                 newSecondaryNetworks = secondaryNetworks,
                                 newIsDefault = connectedEntry?.isDefaultNetwork ?: false,
@@ -277,7 +268,7 @@
         }
 
         val hotspotDeviceType =
-            if (isInstantTetherEnabled && this is HotspotNetworkEntry) {
+            if (this is HotspotNetworkEntry) {
                 this.deviceType.toHotspotDeviceType()
             } else {
                 WifiNetworkModel.HotspotDeviceType.NONE
@@ -408,7 +399,6 @@
     class Factory
     @Inject
     constructor(
-        private val featureFlags: FeatureFlags,
         @Application private val scope: CoroutineScope,
         @Main private val mainExecutor: Executor,
         @Background private val bgDispatcher: CoroutineDispatcher,
@@ -418,7 +408,6 @@
     ) {
         fun create(wifiManager: WifiManager): WifiRepositoryImpl {
             return WifiRepositoryImpl(
-                featureFlags,
                 scope,
                 mainExecutor,
                 bgDispatcher,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/composable/ModeTile.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/composable/ModeTile.kt
index 0e88f44..af93880 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/composable/ModeTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/composable/ModeTile.kt
@@ -90,9 +90,11 @@
                         viewModel.subtext,
                         fontWeight = FontWeight.W400,
                         modifier =
-                            Modifier.tileMarquee().testTag("state").clearAndSetSemantics {
-                                contentDescription = viewModel.subtextDescription
-                            }
+                            Modifier.tileMarquee()
+                                .testTag(if (viewModel.enabled) "stateOn" else "stateOff")
+                                .clearAndSetSemantics {
+                                    contentDescription = viewModel.subtextDescription
+                                }
                     )
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 28effe9..8934d8f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -1280,6 +1280,8 @@
 
     private final class Receiver extends BroadcastReceiver {
 
+        private static final int STREAM_UNKNOWN = -1;
+
         public void init() {
             final IntentFilter filter = new IntentFilter();
             filter.addAction(AudioManager.VOLUME_CHANGED_ACTION);
@@ -1301,30 +1303,39 @@
             final String action = intent.getAction();
             boolean changed = false;
             if (action.equals(AudioManager.VOLUME_CHANGED_ACTION)) {
-                final int stream = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
+                final int stream = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
+                        STREAM_UNKNOWN);
                 final int level = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
                 final int oldLevel = intent
                         .getIntExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, -1);
                 if (D.BUG) Log.d(TAG, "onReceive VOLUME_CHANGED_ACTION stream=" + stream
                         + " level=" + level + " oldLevel=" + oldLevel);
-                changed = updateStreamLevelW(stream, level);
+                if (stream != STREAM_UNKNOWN) {
+                    changed = updateStreamLevelW(stream, level);
+                }
             } else if (action.equals(AudioManager.STREAM_DEVICES_CHANGED_ACTION)) {
-                final int stream = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
+                final int stream = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
+                        STREAM_UNKNOWN);
                 final int devices = intent
                         .getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_DEVICES, -1);
                 final int oldDevices = intent
                         .getIntExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_DEVICES, -1);
                 if (D.BUG) Log.d(TAG, "onReceive STREAM_DEVICES_CHANGED_ACTION stream="
                         + stream + " devices=" + devices + " oldDevices=" + oldDevices);
-                changed = checkRoutedToBluetoothW(stream);
-                changed |= onVolumeChangedW(stream, 0);
+                if (stream != STREAM_UNKNOWN) {
+                    changed |= checkRoutedToBluetoothW(stream);
+                    changed |= onVolumeChangedW(stream, 0);
+                }
             } else if (action.equals(AudioManager.STREAM_MUTE_CHANGED_ACTION)) {
-                final int stream = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
+                final int stream = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
+                        STREAM_UNKNOWN);
                 final boolean muted = intent
                         .getBooleanExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, false);
                 if (D.BUG) Log.d(TAG, "onReceive STREAM_MUTE_CHANGED_ACTION stream=" + stream
                         + " muted=" + muted);
-                changed = updateStreamMuteW(stream, muted);
+                if (stream != STREAM_UNKNOWN) {
+                    changed = updateStreamMuteW(stream, muted);
+                }
             } else if (action.equals(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED)) {
                 if (D.BUG) Log.d(TAG, "onReceive ACTION_EFFECTS_SUPPRESSOR_CHANGED");
                 changed = updateEffectsSuppressorW(mNoMan.getEffectsSuppressor());
diff --git a/packages/SystemUI/tests/Android.bp b/packages/SystemUI/tests/Android.bp
index 88939a2..f601387 100644
--- a/packages/SystemUI/tests/Android.bp
+++ b/packages/SystemUI/tests/Android.bp
@@ -50,3 +50,14 @@
     additional_manifests: ["AndroidManifest.xml"],
     manifest: "AndroidManifest-base.xml",
 }
+
+test_module_config {
+    name: "SystemUITests_systemui_accessibility",
+    base: "SystemUITests",
+    test_suites: ["device-tests"],
+    include_filters: ["com.android.systemui.accessibility"],
+    exclude_annotations: [
+        "android.platform.test.annotations.Postsubmit",
+        "android.platform.test.annotations.FlakyTest",
+    ],
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/EmergencyButtonControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/EmergencyButtonControllerTest.kt
index 347605d..43a78035 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/EmergencyButtonControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/EmergencyButtonControllerTest.kt
@@ -19,6 +19,7 @@
 import android.app.ActivityTaskManager
 import android.content.pm.PackageManager
 import android.os.PowerManager
+import android.platform.test.annotations.EnableFlags
 import android.telecom.TelecomManager
 import android.telephony.TelephonyManager
 import android.testing.TestableLooper
@@ -26,14 +27,20 @@
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.haptics.msdl.FakeMSDLPlayer
+import com.android.systemui.haptics.msdl.msdlPlayer
 import com.android.systemui.shade.ShadeController
 import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.testKosmos
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
+import com.google.android.msdl.data.model.MSDLToken
+import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -64,6 +71,8 @@
     val fakeSystemClock = FakeSystemClock()
     val mainExecutor = FakeExecutor(fakeSystemClock)
     val backgroundExecutor = FakeExecutor(fakeSystemClock)
+    private val kosmos = testKosmos()
+    private val msdlPlayer: FakeMSDLPlayer = kosmos.msdlPlayer
 
     lateinit var underTest: EmergencyButtonController
 
@@ -84,6 +93,7 @@
                 mainExecutor,
                 backgroundExecutor,
                 mSelectedUserInteractor,
+                msdlPlayer,
             )
         context.setMockPackageManager(packageManager)
         Mockito.`when`(emergencyButton.context).thenReturn(context)
@@ -113,4 +123,13 @@
                 /* isSecure= */ eq(true)
             )
     }
+
+    @Test
+    @EnableFlags(Flags.FLAG_MSDL_FEEDBACK)
+    fun takeEmergencyCallAction_withMSDLFeedback_playsEmergencyButtonTokenAndNullAttributes() {
+        underTest.takeEmergencyCallAction()
+
+        assertThat(msdlPlayer.latestTokenPlayed).isEqualTo(MSDLToken.KEYPRESS_RETURN)
+        assertThat(msdlPlayer.latestPropertiesPlayed).isNull()
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
index a18d272..aa8c6b7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
@@ -57,6 +57,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.ambient.touch.dagger.InputSessionComponent;
 import com.android.systemui.kosmos.KosmosJavaAdapter;
+import com.android.systemui.log.LogBufferHelperKt;
 import com.android.systemui.shared.system.InputChannelCompat;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.display.DisplayHelper;
@@ -153,7 +154,8 @@
             when(mWindowManager.getMaximumWindowMetrics()).thenReturn(mWindowMetrics);
             mMonitor = new TouchMonitor(mExecutor, mBackgroundExecutor, mLifecycleRegistry,
                     mInputFactory, mDisplayHelper, mKosmos.getConfigurationInteractor(),
-                    handlers, mIWindowManager,  0);
+                    handlers, mIWindowManager, 0, "TouchMonitorTest",
+                    LogBufferHelperKt.logcatLogBuffer("TouchMonitorTest"));
             clearInvocations(mLifecycleRegistry);
             mMonitor.init();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
index 88bfcf0..a1bea06 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
@@ -39,8 +39,6 @@
 import com.android.internal.logging.testing.FakeMetricsLogger;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingDataProvider.GestureFinalizedListener;
-import com.android.systemui.flags.FakeFeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
@@ -84,7 +82,6 @@
     private AccessibilityManager mAccessibilityManager;
 
     private final FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
-    private final FakeFeatureFlags mFakeFeatureFlags = new FakeFeatureFlags();
 
     private final FalsingClassifier.Result mFalsedResult =
             FalsingClassifier.Result.falsed(1, getClass().getSimpleName(), "");
@@ -110,7 +107,7 @@
         mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider,
                 mMetricsLogger, mClassifiers, mSingleTapClassfier, mLongTapClassifier,
                 mDoubleTapClassifier, mHistoryTracker, mKeyguardStateController,
-                mAccessibilityManager, false, mFakeFeatureFlags);
+                mAccessibilityManager, false);
 
 
         ArgumentCaptor<GestureFinalizedListener> gestureCompleteListenerCaptor =
@@ -120,7 +117,6 @@
                 gestureCompleteListenerCaptor.capture());
 
         mGestureFinalizedListener = gestureCompleteListenerCaptor.getValue();
-        mFakeFeatureFlags.set(Flags.FALSING_OFF_FOR_UNFOLDED, true);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialNotificationCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialNotificationCoordinatorTest.kt
new file mode 100644
index 0000000..945f953
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialNotificationCoordinatorTest.kt
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.inputdevice.tutorial.domain.interactor
+
+import android.app.Notification
+import android.app.NotificationManager
+import androidx.annotation.StringRes
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.inputdevice.tutorial.data.repository.TutorialSchedulerRepository
+import com.android.systemui.inputdevice.tutorial.ui.TutorialNotificationCoordinator
+import com.android.systemui.keyboard.data.repository.FakeKeyboardRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
+import com.android.systemui.touchpad.data.repository.FakeTouchpadRepository
+import com.google.common.truth.Truth.assertThat
+import kotlin.time.Duration.Companion.hours
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runTest
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnit
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class TutorialNotificationCoordinatorTest : SysuiTestCase() {
+
+    private lateinit var underTest: TutorialNotificationCoordinator
+    private val kosmos = Kosmos()
+    private val testScope = kosmos.testScope
+    private val keyboardRepository = FakeKeyboardRepository()
+    private val touchpadRepository = FakeTouchpadRepository()
+    private lateinit var dataStoreScope: CoroutineScope
+    private lateinit var repository: TutorialSchedulerRepository
+    @Mock private lateinit var notificationManager: NotificationManager
+    @Captor private lateinit var notificationCaptor: ArgumentCaptor<Notification>
+    @get:Rule val rule = MockitoJUnit.rule()
+
+    @Before
+    fun setup() {
+        dataStoreScope = CoroutineScope(Dispatchers.Unconfined)
+        repository =
+            TutorialSchedulerRepository(
+                context,
+                dataStoreScope,
+                dataStoreName = "TutorialNotificationCoordinatorTest"
+            )
+        val interactor =
+            TutorialSchedulerInteractor(keyboardRepository, touchpadRepository, repository)
+        underTest =
+            TutorialNotificationCoordinator(
+                testScope.backgroundScope,
+                context,
+                interactor,
+                notificationManager
+            )
+        notificationCaptor = ArgumentCaptor.forClass(Notification::class.java)
+        underTest.start()
+    }
+
+    @After
+    fun clear() {
+        runBlocking { repository.clearDataStore() }
+        dataStoreScope.cancel()
+    }
+
+    @Test
+    fun showKeyboardNotification() =
+        testScope.runTest {
+            keyboardRepository.setIsAnyKeyboardConnected(true)
+            advanceTimeBy(LAUNCH_DELAY)
+            verifyNotification(
+                R.string.launch_keyboard_tutorial_notification_title,
+                R.string.launch_keyboard_tutorial_notification_content
+            )
+        }
+
+    @Test
+    fun showTouchpadNotification() =
+        testScope.runTest {
+            touchpadRepository.setIsAnyTouchpadConnected(true)
+            advanceTimeBy(LAUNCH_DELAY)
+            verifyNotification(
+                R.string.launch_touchpad_tutorial_notification_title,
+                R.string.launch_touchpad_tutorial_notification_content
+            )
+        }
+
+    @Test
+    fun showKeyboardTouchpadNotification() =
+        testScope.runTest {
+            keyboardRepository.setIsAnyKeyboardConnected(true)
+            touchpadRepository.setIsAnyTouchpadConnected(true)
+            advanceTimeBy(LAUNCH_DELAY)
+            verifyNotification(
+                R.string.launch_keyboard_touchpad_tutorial_notification_title,
+                R.string.launch_keyboard_touchpad_tutorial_notification_content
+            )
+        }
+
+    @Test
+    fun doNotShowNotification() =
+        testScope.runTest {
+            advanceTimeBy(LAUNCH_DELAY)
+            verify(notificationManager, never()).notify(eq(TAG), eq(NOTIFICATION_ID), any())
+        }
+
+    private fun verifyNotification(@StringRes titleResId: Int, @StringRes contentResId: Int) {
+        verify(notificationManager)
+            .notify(eq(TAG), eq(NOTIFICATION_ID), notificationCaptor.capture())
+        val notification = notificationCaptor.value
+        val actualTitle = notification.getString(Notification.EXTRA_TITLE)
+        val actualContent = notification.getString(Notification.EXTRA_TEXT)
+        assertThat(actualTitle).isEqualTo(context.getString(titleResId))
+        assertThat(actualContent).isEqualTo(context.getString(contentResId))
+    }
+
+    private fun Notification.getString(key: String): String =
+        this.extras?.getCharSequence(key).toString()
+
+    companion object {
+        private const val TAG = "TutorialSchedulerInteractor"
+        private const val NOTIFICATION_ID = 5566
+        private val LAUNCH_DELAY = 72.hours
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt
index 432f7af..650f9dc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt
@@ -32,6 +32,8 @@
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.cancel
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runTest
@@ -63,13 +65,7 @@
                 dataStoreName = "TutorialSchedulerInteractorTest"
             )
         underTest =
-            TutorialSchedulerInteractor(
-                testScope.backgroundScope,
-                keyboardRepository,
-                touchpadRepository,
-                schedulerRepository
-            )
-        underTest.start()
+            TutorialSchedulerInteractor(keyboardRepository, touchpadRepository, schedulerRepository)
     }
 
     @After
@@ -81,80 +77,90 @@
     @Test
     fun connectKeyboard_delayElapse_launchForKeyboard() =
         testScope.runTest {
+            launchAndAssert(TutorialType.KEYBOARD)
+
             keyboardRepository.setIsAnyKeyboardConnected(true)
             advanceTimeBy(LAUNCH_DELAY)
-            assertLaunch(TutorialType.KEYBOARD)
         }
 
     @Test
     fun connectBothDevices_delayElapse_launchForBoth() =
         testScope.runTest {
+            launchAndAssert(TutorialType.BOTH)
+
             keyboardRepository.setIsAnyKeyboardConnected(true)
             touchpadRepository.setIsAnyTouchpadConnected(true)
             advanceTimeBy(LAUNCH_DELAY)
-            assertLaunch(TutorialType.BOTH)
         }
 
     @Test
     fun connectBothDevice_delayNotElapse_launchNothing() =
         testScope.runTest {
+            launchAndAssert(TutorialType.NONE)
+
             keyboardRepository.setIsAnyKeyboardConnected(true)
             touchpadRepository.setIsAnyTouchpadConnected(true)
             advanceTimeBy(A_SHORT_PERIOD_OF_TIME)
-            assertLaunch(TutorialType.NONE)
         }
 
     @Test
     fun nothingConnect_delayElapse_launchNothing() =
         testScope.runTest {
+            launchAndAssert(TutorialType.NONE)
+
             keyboardRepository.setIsAnyKeyboardConnected(false)
             touchpadRepository.setIsAnyTouchpadConnected(false)
             advanceTimeBy(LAUNCH_DELAY)
-            assertLaunch(TutorialType.NONE)
         }
 
     @Test
     fun connectKeyboard_thenTouchpad_delayElapse_launchForBoth() =
         testScope.runTest {
+            launchAndAssert(TutorialType.BOTH)
+
             keyboardRepository.setIsAnyKeyboardConnected(true)
             advanceTimeBy(A_SHORT_PERIOD_OF_TIME)
             touchpadRepository.setIsAnyTouchpadConnected(true)
             advanceTimeBy(REMAINING_TIME)
-            assertLaunch(TutorialType.BOTH)
         }
 
     @Test
     fun connectKeyboard_thenTouchpad_removeKeyboard_delayElapse_launchNothing() =
         testScope.runTest {
+            launchAndAssert(TutorialType.NONE)
+
             keyboardRepository.setIsAnyKeyboardConnected(true)
             advanceTimeBy(A_SHORT_PERIOD_OF_TIME)
             touchpadRepository.setIsAnyTouchpadConnected(true)
             keyboardRepository.setIsAnyKeyboardConnected(false)
             advanceTimeBy(REMAINING_TIME)
-            assertLaunch(TutorialType.NONE)
         }
 
-    // TODO: likely to be changed after we update TutorialSchedulerInteractor.launchTutorial
-    private suspend fun assertLaunch(tutorialType: TutorialType) {
-        when (tutorialType) {
-            TutorialType.KEYBOARD -> {
-                assertThat(schedulerRepository.isLaunched(DeviceType.KEYBOARD)).isTrue()
-                assertThat(schedulerRepository.isLaunched(DeviceType.TOUCHPAD)).isFalse()
-            }
-            TutorialType.TOUCHPAD -> {
-                assertThat(schedulerRepository.isLaunched(DeviceType.KEYBOARD)).isFalse()
-                assertThat(schedulerRepository.isLaunched(DeviceType.TOUCHPAD)).isTrue()
-            }
-            TutorialType.BOTH -> {
-                assertThat(schedulerRepository.isLaunched(DeviceType.KEYBOARD)).isTrue()
-                assertThat(schedulerRepository.isLaunched(DeviceType.TOUCHPAD)).isTrue()
-            }
-            TutorialType.NONE -> {
-                assertThat(schedulerRepository.isLaunched(DeviceType.KEYBOARD)).isFalse()
-                assertThat(schedulerRepository.isLaunched(DeviceType.TOUCHPAD)).isFalse()
+    private suspend fun launchAndAssert(expectedTutorial: TutorialType) =
+        testScope.backgroundScope.launch {
+            val actualTutorial = underTest.tutorials.first()
+            assertThat(actualTutorial).isEqualTo(expectedTutorial)
+
+            // TODO: need to update after we move launch into the tutorial
+            when (expectedTutorial) {
+                TutorialType.KEYBOARD -> {
+                    assertThat(schedulerRepository.isLaunched(DeviceType.KEYBOARD)).isTrue()
+                    assertThat(schedulerRepository.isLaunched(DeviceType.TOUCHPAD)).isFalse()
+                }
+                TutorialType.TOUCHPAD -> {
+                    assertThat(schedulerRepository.isLaunched(DeviceType.KEYBOARD)).isFalse()
+                    assertThat(schedulerRepository.isLaunched(DeviceType.TOUCHPAD)).isTrue()
+                }
+                TutorialType.BOTH -> {
+                    assertThat(schedulerRepository.isLaunched(DeviceType.KEYBOARD)).isTrue()
+                    assertThat(schedulerRepository.isLaunched(DeviceType.TOUCHPAD)).isTrue()
+                }
+                TutorialType.NONE -> {
+                    assertThat(schedulerRepository.isLaunched(DeviceType.KEYBOARD)).isFalse()
+                    assertThat(schedulerRepository.isLaunched(DeviceType.TOUCHPAD)).isFalse()
+                }
             }
         }
-    }
 
     companion object {
         private val LAUNCH_DELAY = 72.hours
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt
index fd53b5ba..ad7a5b6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt
@@ -56,7 +56,6 @@
 import com.android.systemui.flags.Flags.MEDIA_RESUME_PROGRESS
 import com.android.systemui.flags.Flags.MEDIA_RETAIN_RECOMMENDATIONS
 import com.android.systemui.flags.Flags.MEDIA_RETAIN_SESSIONS
-import com.android.systemui.flags.Flags.MEDIA_SESSION_ACTIONS
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
@@ -317,7 +316,6 @@
         whenever(mediaSmartspaceTarget.iconGrid).thenReturn(validRecommendationList)
         whenever(mediaSmartspaceTarget.creationTimeMillis).thenReturn(SMARTSPACE_CREATION_TIME)
         whenever(mediaSmartspaceTarget.expiryTimeMillis).thenReturn(SMARTSPACE_EXPIRY_TIME)
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, false)
         fakeFeatureFlags.set(MEDIA_RETAIN_SESSIONS, false)
         fakeFeatureFlags.set(MEDIA_RESUME_PROGRESS, false)
         fakeFeatureFlags.set(MEDIA_REMOTE_RESUME, false)
@@ -1671,7 +1669,6 @@
     @Test
     fun testPlaybackActions_noState_usesNotification() {
         val desc = "Notification Action"
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         whenever(controller.playbackState).thenReturn(null)
 
         val notifWithAction =
@@ -1705,7 +1702,6 @@
     @Test
     fun testPlaybackActions_hasPrevNext() {
         val customDesc = arrayOf("custom 1", "custom 2", "custom 3", "custom 4")
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         val stateActions =
             PlaybackState.ACTION_PLAY or
                 PlaybackState.ACTION_SKIP_TO_PREVIOUS or
@@ -1749,7 +1745,6 @@
     @Test
     fun testPlaybackActions_noPrevNext_usesCustom() {
         val customDesc = arrayOf("custom 1", "custom 2", "custom 3", "custom 4", "custom 5")
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         val stateActions = PlaybackState.ACTION_PLAY
         val stateBuilder = PlaybackState.Builder().setActions(stateActions)
         customDesc.forEach {
@@ -1781,7 +1776,6 @@
 
     @Test
     fun testPlaybackActions_connecting() {
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         val stateActions = PlaybackState.ACTION_PLAY
         val stateBuilder =
             PlaybackState.Builder()
@@ -1802,7 +1796,6 @@
     @Test
     fun testPlaybackActions_reservedSpace() {
         val customDesc = arrayOf("custom 1", "custom 2", "custom 3", "custom 4")
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         val stateActions = PlaybackState.ACTION_PLAY
         val stateBuilder = PlaybackState.Builder().setActions(stateActions)
         customDesc.forEach {
@@ -1840,7 +1833,6 @@
 
     @Test
     fun testPlaybackActions_playPause_hasButton() {
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         val stateActions = PlaybackState.ACTION_PLAY_PAUSE
         val stateBuilder = PlaybackState.Builder().setActions(stateActions)
         whenever(controller.playbackState).thenReturn(stateBuilder.build())
@@ -1939,7 +1931,6 @@
 
     @Test
     fun testPlaybackState_PauseWhenFlagTrue_keyExists_callsListener() {
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         val state = PlaybackState.Builder().setState(PlaybackState.STATE_PAUSED, 0L, 1f).build()
         whenever(controller.playbackState).thenReturn(state)
 
@@ -2161,7 +2152,6 @@
     @Test
     fun testRetain_sessionPlayer_notifRemoved_doesNotChange() {
         fakeFeatureFlags.set(MEDIA_RETAIN_SESSIONS, true)
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         addPlaybackStateAction()
 
         // When a media control with PlaybackState actions is added, times out,
@@ -2181,7 +2171,6 @@
     @Test
     fun testRetain_sessionPlayer_sessionDestroyed_setToResume() {
         fakeFeatureFlags.set(MEDIA_RETAIN_SESSIONS, true)
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         addPlaybackStateAction()
 
         // When a media control with PlaybackState actions is added, times out,
@@ -2215,7 +2204,6 @@
     @Test
     fun testRetain_sessionPlayer_destroyedWhileActive_noResume_fullyRemoved() {
         fakeFeatureFlags.set(MEDIA_RETAIN_SESSIONS, true)
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         addPlaybackStateAction()
 
         // When a media control using session actions is added, and then the session is destroyed
@@ -2235,7 +2223,6 @@
     @Test
     fun testRetain_sessionPlayer_canResume_destroyedWhileActive_setToResume() {
         fakeFeatureFlags.set(MEDIA_RETAIN_SESSIONS, true)
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         addPlaybackStateAction()
 
         // When a media control using session actions and that does allow resumption is added,
@@ -2268,7 +2255,6 @@
 
     @Test
     fun testSessionPlayer_sessionDestroyed_noResume_fullyRemoved() {
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         addPlaybackStateAction()
 
         // When a media control with PlaybackState actions is added, times out,
@@ -2295,7 +2281,6 @@
 
     @Test
     fun testSessionPlayer_destroyedWhileActive_noResume_fullyRemoved() {
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         addPlaybackStateAction()
 
         // When a media control using session actions is added, and then the session is destroyed
@@ -2314,7 +2299,6 @@
 
     @Test
     fun testSessionPlayer_canResume_destroyedWhileActive_setToResume() {
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         addPlaybackStateAction()
 
         // When a media control using session actions and that does allow resumption is added,
@@ -2348,7 +2332,6 @@
     @Test
     fun testSessionDestroyed_noNotificationKey_stillRemoved() {
         fakeFeatureFlags.set(MEDIA_RETAIN_SESSIONS, true)
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
 
         // When a notiifcation is added and then removed before it is fully processed
         mediaDataManager.onNotificationAdded(KEY, mediaNotification)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt
index f4c2b47..c0f503d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt
@@ -61,7 +61,6 @@
 import com.android.systemui.flags.Flags.MEDIA_RESUME_PROGRESS
 import com.android.systemui.flags.Flags.MEDIA_RETAIN_RECOMMENDATIONS
 import com.android.systemui.flags.Flags.MEDIA_RETAIN_SESSIONS
-import com.android.systemui.flags.Flags.MEDIA_SESSION_ACTIONS
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
@@ -338,7 +337,6 @@
         whenever(mediaSmartspaceTarget.iconGrid).thenReturn(validRecommendationList)
         whenever(mediaSmartspaceTarget.creationTimeMillis).thenReturn(SMARTSPACE_CREATION_TIME)
         whenever(mediaSmartspaceTarget.expiryTimeMillis).thenReturn(SMARTSPACE_EXPIRY_TIME)
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, false)
         fakeFeatureFlags.set(MEDIA_RETAIN_SESSIONS, false)
         fakeFeatureFlags.set(MEDIA_RESUME_PROGRESS, false)
         fakeFeatureFlags.set(MEDIA_REMOTE_RESUME, false)
@@ -1680,7 +1678,6 @@
     @Test
     fun testPlaybackActions_noState_usesNotification() {
         val desc = "Notification Action"
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         whenever(controller.playbackState).thenReturn(null)
 
         val notifWithAction =
@@ -1714,7 +1711,6 @@
     @Test
     fun testPlaybackActions_hasPrevNext() {
         val customDesc = arrayOf("custom 1", "custom 2", "custom 3", "custom 4")
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         val stateActions =
             PlaybackState.ACTION_PLAY or
                 PlaybackState.ACTION_SKIP_TO_PREVIOUS or
@@ -1758,7 +1754,6 @@
     @Test
     fun testPlaybackActions_noPrevNext_usesCustom() {
         val customDesc = arrayOf("custom 1", "custom 2", "custom 3", "custom 4", "custom 5")
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         val stateActions = PlaybackState.ACTION_PLAY
         val stateBuilder = PlaybackState.Builder().setActions(stateActions)
         customDesc.forEach {
@@ -1790,7 +1785,6 @@
 
     @Test
     fun testPlaybackActions_connecting() {
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         val stateActions = PlaybackState.ACTION_PLAY
         val stateBuilder =
             PlaybackState.Builder()
@@ -1811,7 +1805,6 @@
     @Test
     @EnableFlags(Flags.FLAG_MEDIA_CONTROLS_DRAWABLES_REUSE)
     fun postWithPlaybackActions_drawablesReused() {
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true)
         whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true)
         val stateActions =
@@ -1845,7 +1838,6 @@
     @Test
     @DisableFlags(Flags.FLAG_MEDIA_CONTROLS_DRAWABLES_REUSE)
     fun postWithPlaybackActions_drawablesNotReused() {
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true)
         whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true)
         val stateActions =
@@ -1879,7 +1871,6 @@
     @Test
     fun testPlaybackActions_reservedSpace() {
         val customDesc = arrayOf("custom 1", "custom 2", "custom 3", "custom 4")
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         val stateActions = PlaybackState.ACTION_PLAY
         val stateBuilder = PlaybackState.Builder().setActions(stateActions)
         customDesc.forEach {
@@ -1917,7 +1908,6 @@
 
     @Test
     fun testPlaybackActions_playPause_hasButton() {
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         val stateActions = PlaybackState.ACTION_PLAY_PAUSE
         val stateBuilder = PlaybackState.Builder().setActions(stateActions)
         whenever(controller.playbackState).thenReturn(stateBuilder.build())
@@ -2016,7 +2006,6 @@
 
     @Test
     fun testPlaybackState_PauseWhenFlagTrue_keyExists_callsListener() {
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         val state = PlaybackState.Builder().setState(PlaybackState.STATE_PAUSED, 0L, 1f).build()
         whenever(controller.playbackState).thenReturn(state)
 
@@ -2237,7 +2226,6 @@
     @Test
     fun testRetain_sessionPlayer_notifRemoved_doesNotChange() {
         fakeFeatureFlags.set(MEDIA_RETAIN_SESSIONS, true)
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         addPlaybackStateAction()
 
         // When a media control with PlaybackState actions is added, times out,
@@ -2257,7 +2245,6 @@
     @Test
     fun testRetain_sessionPlayer_sessionDestroyed_setToResume() {
         fakeFeatureFlags.set(MEDIA_RETAIN_SESSIONS, true)
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         addPlaybackStateAction()
 
         // When a media control with PlaybackState actions is added, times out,
@@ -2291,7 +2278,6 @@
     @Test
     fun testRetain_sessionPlayer_destroyedWhileActive_noResume_fullyRemoved() {
         fakeFeatureFlags.set(MEDIA_RETAIN_SESSIONS, true)
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         addPlaybackStateAction()
 
         // When a media control using session actions is added, and then the session is destroyed
@@ -2311,7 +2297,6 @@
     @Test
     fun testRetain_sessionPlayer_canResume_destroyedWhileActive_setToResume() {
         fakeFeatureFlags.set(MEDIA_RETAIN_SESSIONS, true)
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         addPlaybackStateAction()
 
         // When a media control using session actions and that does allow resumption is added,
@@ -2344,7 +2329,6 @@
 
     @Test
     fun testSessionPlayer_sessionDestroyed_noResume_fullyRemoved() {
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         addPlaybackStateAction()
 
         // When a media control with PlaybackState actions is added, times out,
@@ -2371,7 +2355,6 @@
 
     @Test
     fun testSessionPlayer_destroyedWhileActive_noResume_fullyRemoved() {
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         addPlaybackStateAction()
 
         // When a media control using session actions is added, and then the session is destroyed
@@ -2390,7 +2373,6 @@
 
     @Test
     fun testSessionPlayer_canResume_destroyedWhileActive_setToResume() {
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
         addPlaybackStateAction()
 
         // When a media control using session actions and that does allow resumption is added,
@@ -2424,7 +2406,6 @@
     @Test
     fun testSessionDestroyed_noNotificationKey_stillRemoved() {
         fakeFeatureFlags.set(MEDIA_RETAIN_SESSIONS, true)
-        fakeFeatureFlags.set(MEDIA_SESSION_ACTIONS, true)
 
         // When a notiifcation is added and then removed before it is fully processed
         mediaDataProcessor.onNotificationAdded(KEY, mediaNotification)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recordissue/IssueRecordingStateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/recordissue/IssueRecordingStateTest.kt
new file mode 100644
index 0000000..4ab3c7b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/recordissue/IssueRecordingStateTest.kt
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recordissue
+
+import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.settings.userFileManager
+import com.android.systemui.settings.userTracker
+import com.google.common.truth.Truth
+import java.util.concurrent.CountDownLatch
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class IssueRecordingStateTest : SysuiTestCase() {
+
+    private val kosmos = Kosmos()
+    private lateinit var underTest: IssueRecordingState
+
+    @Before
+    fun setup() {
+        underTest = IssueRecordingState(kosmos.userTracker, kosmos.userFileManager)
+    }
+
+    @Test
+    fun takeBugreport_isSaved_betweenDifferentSessions() {
+        val expected = true
+
+        underTest.takeBugreport = expected
+        underTest = IssueRecordingState(kosmos.userTracker, kosmos.userFileManager)
+
+        Truth.assertThat(underTest.takeBugreport).isEqualTo(expected)
+    }
+
+    @Test
+    fun recordScreen_isSaved_betweenDifferentSessions() {
+        val expected = true
+
+        underTest.recordScreen = expected
+        underTest = IssueRecordingState(kosmos.userTracker, kosmos.userFileManager)
+
+        Truth.assertThat(underTest.recordScreen).isEqualTo(expected)
+    }
+
+    @Test
+    fun hasUserApprovedScreenRecording_isTrue_afterBeingMarkedAsCompleted() {
+        underTest.markUserApprovalForScreenRecording()
+        underTest = IssueRecordingState(kosmos.userTracker, kosmos.userFileManager)
+
+        Truth.assertThat(underTest.hasUserApprovedScreenRecording).isEqualTo(true)
+    }
+
+    @Test
+    fun tagTitles_areSavedConsistently() {
+        val expected = setOf("a", "b", "c")
+
+        underTest.tagTitles = expected
+        underTest = IssueRecordingState(kosmos.userTracker, kosmos.userFileManager)
+
+        Truth.assertThat(underTest.tagTitles).isEqualTo(expected)
+    }
+
+    @Test
+    fun isRecording_callsListeners_onTheValueChanging() {
+        val count = CountDownLatch(1)
+        val listener = Runnable { count.countDown() }
+
+        underTest.addListener(listener)
+        underTest.isRecording = true
+
+        Truth.assertThat(count.count).isEqualTo(0)
+    }
+
+    @Test
+    fun isRecording_callsOnlyListeners_whoHaveNotBeenRemoved() {
+        val count1 = CountDownLatch(1)
+        val count2 = CountDownLatch(1)
+        val listener1 = Runnable { count1.countDown() }
+        val listener2 = Runnable { count2.countDown() }
+
+        underTest.addListener(listener1)
+        underTest.removeListener(listener1)
+        underTest.addListener(listener2)
+        underTest.isRecording = true
+
+        Truth.assertThat(count1.count).isEqualTo(1)
+        Truth.assertThat(count2.count).isEqualTo(0)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
index 3ba1447e..c0444fe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
@@ -117,7 +117,8 @@
             object : AmbientTouchComponent.Factory {
                 override fun create(
                     lifecycleOwner: LifecycleOwner,
-                    touchHandlers: Set<TouchHandler>
+                    touchHandlers: Set<TouchHandler>,
+                    loggingName: String
                 ): AmbientTouchComponent =
                     object : AmbientTouchComponent {
                         override fun getTouchMonitor(): TouchMonitor = touchMonitor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
index a0d231b..60a1855 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
@@ -51,6 +51,7 @@
 import android.platform.test.annotations.EnableFlags;
 import android.service.notification.StatusBarNotification;
 import android.view.ViewGroup;
+import android.widget.ImageView;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -431,6 +432,32 @@
                 mIconView.getIconScale(), 0.01f);
     }
 
+    @Test
+    @EnableFlags({Flags.FLAG_MODES_UI, Flags.FLAG_MODES_UI_ICONS})
+    public void set_iconThatWantsFixedSpace_setsScaleType() {
+        mIconView.setScaleType(ImageView.ScaleType.FIT_START);
+        StatusBarIcon icon = new StatusBarIcon(UserHandle.ALL, "mockPackage",
+                Icon.createWithResource(mContext, R.drawable.ic_android), 0, 0, "",
+                StatusBarIcon.Type.SystemIcon, StatusBarIcon.Shape.FIXED_SPACE);
+
+        mIconView.set(icon);
+
+        assertThat(mIconView.getScaleType()).isEqualTo(ImageView.ScaleType.FIT_CENTER);
+    }
+
+    @Test
+    @EnableFlags({Flags.FLAG_MODES_UI, Flags.FLAG_MODES_UI_ICONS})
+    public void set_iconWithOtherShape_keepsScaleType() {
+        mIconView.setScaleType(ImageView.ScaleType.FIT_START);
+        StatusBarIcon icon = new StatusBarIcon(UserHandle.ALL, "mockPackage",
+                Icon.createWithResource(mContext, R.drawable.ic_android), 0, 0, "",
+                StatusBarIcon.Type.SystemIcon, StatusBarIcon.Shape.WRAP_CONTENT);
+
+        mIconView.set(icon);
+
+        assertThat(mIconView.getScaleType()).isEqualTo(ImageView.ScaleType.FIT_START);
+    }
+
     private static StatusBarNotification getMockSbn() {
         StatusBarNotification sbn = mock(StatusBarNotification.class);
         when(sbn.getNotification()).thenReturn(mock(Notification.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
index bd5df07..f528ebb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
@@ -107,69 +107,69 @@
     }
 
     @Test
-    fun chip_allHidden_hidden() =
+    fun primaryChip_allHidden_hidden() =
         testScope.runTest {
             screenRecordState.value = ScreenRecordModel.DoingNothing
             mediaProjectionState.value = MediaProjectionState.NotProjecting
             callRepo.setOngoingCallState(OngoingCallModel.NoCall)
 
-            val latest by collectLastValue(underTest.chip)
+            val latest by collectLastValue(underTest.primaryChip)
 
             assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
         }
 
     @Test
-    fun chip_screenRecordShow_restHidden_screenRecordShown() =
+    fun primaryChip_screenRecordShow_restHidden_screenRecordShown() =
         testScope.runTest {
             screenRecordState.value = ScreenRecordModel.Recording
             mediaProjectionState.value = MediaProjectionState.NotProjecting
             callRepo.setOngoingCallState(OngoingCallModel.NoCall)
 
-            val latest by collectLastValue(underTest.chip)
+            val latest by collectLastValue(underTest.primaryChip)
 
             assertIsScreenRecordChip(latest)
         }
 
     @Test
-    fun chip_screenRecordShowAndCallShow_screenRecordShown() =
+    fun primaryChip_screenRecordShowAndCallShow_screenRecordShown() =
         testScope.runTest {
             screenRecordState.value = ScreenRecordModel.Recording
 
             callRepo.setOngoingCallState(inCallModel(startTimeMs = 34))
 
-            val latest by collectLastValue(underTest.chip)
+            val latest by collectLastValue(underTest.primaryChip)
 
             assertIsScreenRecordChip(latest)
         }
 
     @Test
-    fun chip_screenRecordShowAndShareToAppShow_screenRecordShown() =
+    fun primaryChip_screenRecordShowAndShareToAppShow_screenRecordShown() =
         testScope.runTest {
             screenRecordState.value = ScreenRecordModel.Recording
             mediaProjectionState.value =
                 MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
             callRepo.setOngoingCallState(OngoingCallModel.NoCall)
 
-            val latest by collectLastValue(underTest.chip)
+            val latest by collectLastValue(underTest.primaryChip)
 
             assertIsScreenRecordChip(latest)
         }
 
     @Test
-    fun chip_shareToAppShowAndCallShow_shareToAppShown() =
+    fun primaryChip_shareToAppShowAndCallShow_shareToAppShown() =
         testScope.runTest {
             screenRecordState.value = ScreenRecordModel.DoingNothing
             mediaProjectionState.value =
                 MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
             callRepo.setOngoingCallState(inCallModel(startTimeMs = 34))
 
-            val latest by collectLastValue(underTest.chip)
+            val latest by collectLastValue(underTest.primaryChip)
 
             assertIsShareToAppChip(latest)
         }
 
     @Test
-    fun chip_screenRecordAndShareToAppAndCastToOtherHideAndCallShown_callShown() =
+    fun primaryChip_screenRecordAndShareToAppAndCastToOtherHideAndCallShown_callShown() =
         testScope.runTest {
             screenRecordState.value = ScreenRecordModel.DoingNothing
             // MediaProjection covers both share-to-app and cast-to-other-device
@@ -177,14 +177,14 @@
 
             callRepo.setOngoingCallState(inCallModel(startTimeMs = 34))
 
-            val latest by collectLastValue(underTest.chip)
+            val latest by collectLastValue(underTest.primaryChip)
 
             assertIsCallChip(latest)
         }
 
     @Test
     @EnableFlags(FLAG_STATUS_BAR_RON_CHIPS)
-    fun chip_higherPriorityChipAdded_lowerPriorityChipReplaced() =
+    fun primaryChip_higherPriorityChipAdded_lowerPriorityChipReplaced() =
         testScope.runTest {
             // Start with just the lowest priority chip shown
             addDemoRonChip(commandRegistry, pw)
@@ -193,7 +193,7 @@
             mediaProjectionState.value = MediaProjectionState.NotProjecting
             screenRecordState.value = ScreenRecordModel.DoingNothing
 
-            val latest by collectLastValue(underTest.chip)
+            val latest by collectLastValue(underTest.primaryChip)
 
             assertIsDemoRonChip(latest)
 
@@ -223,7 +223,7 @@
 
     @Test
     @EnableFlags(FLAG_STATUS_BAR_RON_CHIPS)
-    fun chip_highestPriorityChipRemoved_showsNextPriorityChip() =
+    fun primaryChip_highestPriorityChipRemoved_showsNextPriorityChip() =
         testScope.runTest {
             // WHEN all chips are active
             screenRecordState.value = ScreenRecordModel.Recording
@@ -232,7 +232,7 @@
             callRepo.setOngoingCallState(inCallModel(startTimeMs = 34))
             addDemoRonChip(commandRegistry, pw)
 
-            val latest by collectLastValue(underTest.chip)
+            val latest by collectLastValue(underTest.primaryChip)
 
             // THEN the highest priority screen record is used
             assertIsScreenRecordChip(latest)
@@ -258,11 +258,11 @@
 
     /** Regression test for b/347726238. */
     @Test
-    fun chip_timerDoesNotResetAfterSubscribersRestart() =
+    fun primaryChip_timerDoesNotResetAfterSubscribersRestart() =
         testScope.runTest {
             var latest: OngoingActivityChipModel? = null
 
-            val job1 = underTest.chip.onEach { latest = it }.launchIn(this)
+            val job1 = underTest.primaryChip.onEach { latest = it }.launchIn(this)
 
             // Start a chip with a timer
             systemClock.setElapsedRealtime(1234)
@@ -279,7 +279,7 @@
             systemClock.setElapsedRealtime(5678)
 
             // WHEN we re-subscribe to the chip flow
-            val job2 = underTest.chip.onEach { latest = it }.launchIn(this)
+            val job2 = underTest.primaryChip.onEach { latest = it }.launchIn(this)
 
             runCurrent()
 
@@ -290,13 +290,13 @@
         }
 
     @Test
-    fun chip_screenRecordStoppedViaDialog_chipHiddenWithoutAnimation() =
+    fun primaryChip_screenRecordStoppedViaDialog_chipHiddenWithoutAnimation() =
         testScope.runTest {
             screenRecordState.value = ScreenRecordModel.Recording
             mediaProjectionState.value = MediaProjectionState.NotProjecting
             callRepo.setOngoingCallState(OngoingCallModel.NoCall)
 
-            val latest by collectLastValue(underTest.chip)
+            val latest by collectLastValue(underTest.primaryChip)
 
             assertIsScreenRecordChip(latest)
 
@@ -310,14 +310,14 @@
         }
 
     @Test
-    fun chip_projectionStoppedViaDialog_chipHiddenWithoutAnimation() =
+    fun primaryChip_projectionStoppedViaDialog_chipHiddenWithoutAnimation() =
         testScope.runTest {
             mediaProjectionState.value =
                 MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
             screenRecordState.value = ScreenRecordModel.DoingNothing
             callRepo.setOngoingCallState(OngoingCallModel.NoCall)
 
-            val latest by collectLastValue(underTest.chip)
+            val latest by collectLastValue(underTest.primaryChip)
 
             assertIsShareToAppChip(latest)
 
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 a18de68..a06f4d2 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
@@ -95,6 +95,8 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun;
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds;
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -893,7 +895,7 @@
 
     @Test
     @DisableFlags({QSComposeFragment.FLAG_NAME, NewQsUI.FLAG_NAME})
-    @DisableSceneContainer // TODO(b/312473478): address lack of QS Header
+    @DisableSceneContainer
     public void testInsideQSHeader_noOffset() {
         ViewGroup qsHeader = mock(ViewGroup.class);
         Rect boundsOnScreen = new Rect(0, 0, 1000, 1000);
@@ -911,7 +913,7 @@
 
     @Test
     @DisableFlags({QSComposeFragment.FLAG_NAME, NewQsUI.FLAG_NAME})
-    @DisableSceneContainer // TODO(b/312473478): address lack of QS Header
+    @DisableSceneContainer
     public void testInsideQSHeader_Offset() {
         ViewGroup qsHeader = mock(ViewGroup.class);
         Rect boundsOnScreen = new Rect(100, 100, 1000, 1000);
@@ -932,7 +934,7 @@
 
     @Test
     @EnableFlags({QSComposeFragment.FLAG_NAME, NewQsUI.FLAG_NAME})
-    @DisableSceneContainer // TODO(b/312473478): address lack of QS Header
+    @DisableSceneContainer
     public void testInsideQSHeader_noOffset_qsCompose() {
         ViewGroup qsHeader = mock(ViewGroup.class);
         Rect boundsOnScreen = new Rect(0, 0, 1000, 1000);
@@ -959,7 +961,7 @@
 
     @Test
     @EnableFlags({QSComposeFragment.FLAG_NAME, NewQsUI.FLAG_NAME})
-    @DisableSceneContainer // TODO(b/312473478): address lack of QS Header
+    @DisableSceneContainer
     public void testInsideQSHeader_Offset_qsCompose() {
         ViewGroup qsHeader = mock(ViewGroup.class);
         Rect boundsOnScreen = new Rect(100, 100, 1000, 1000);
@@ -988,6 +990,53 @@
     }
 
     @Test
+    @EnableSceneContainer
+    public void testIsInsideScrollableRegion_noScrim() {
+        mStackScroller.setLeftTopRightBottom(0, 0, 2000, 2000);
+
+        MotionEvent event = transformEventForView(createMotionEvent(250f, 250f), mStackScroller);
+        assertThat(mStackScroller.isInScrollableRegion(event)).isTrue();
+    }
+
+    @Test
+    @EnableSceneContainer
+    public void testIsInsideScrollableRegion_noOffset() {
+        mStackScroller.setLeftTopRightBottom(0, 0, 1000, 2000);
+        mStackScroller.setScrimClippingShape(createScrimShape(100, 500, 900, 2000));
+
+        MotionEvent event1 = transformEventForView(createMotionEvent(500f, 400f), mStackScroller);
+        assertThat(mStackScroller.isInScrollableRegion(event1)).isFalse();
+
+        MotionEvent event2 = transformEventForView(createMotionEvent(50, 1000f), mStackScroller);
+        assertThat(mStackScroller.isInScrollableRegion(event2)).isFalse();
+
+        MotionEvent event3 = transformEventForView(createMotionEvent(950f, 1000f), mStackScroller);
+        assertThat(mStackScroller.isInScrollableRegion(event3)).isFalse();
+
+        MotionEvent event4 = transformEventForView(createMotionEvent(500f, 1000f), mStackScroller);
+        assertThat(mStackScroller.isInScrollableRegion(event4)).isTrue();
+    }
+
+    @Test
+    @EnableSceneContainer
+    public void testIsInsideScrollableRegion_offset() {
+        mStackScroller.setLeftTopRightBottom(1000, 0, 2000, 2000);
+        mStackScroller.setScrimClippingShape(createScrimShape(100, 500, 900, 2000));
+
+        MotionEvent event1 = transformEventForView(createMotionEvent(1500f, 400f), mStackScroller);
+        assertThat(mStackScroller.isInScrollableRegion(event1)).isFalse();
+
+        MotionEvent event2 = transformEventForView(createMotionEvent(1050, 1000f), mStackScroller);
+        assertThat(mStackScroller.isInScrollableRegion(event2)).isFalse();
+
+        MotionEvent event3 = transformEventForView(createMotionEvent(1950f, 1000f), mStackScroller);
+        assertThat(mStackScroller.isInScrollableRegion(event3)).isFalse();
+
+        MotionEvent event4 = transformEventForView(createMotionEvent(1500f, 1000f), mStackScroller);
+        assertThat(mStackScroller.isInScrollableRegion(event4)).isTrue();
+    }
+
+    @Test
     @DisableSceneContainer // TODO(b/312473478): address disabled test
     public void setFractionToShade_recomputesStackHeight() {
         mStackScroller.setFractionToShade(1f);
@@ -1438,7 +1487,7 @@
     private static MotionEvent transformEventForView(MotionEvent event, View view) {
         // From `ViewGroup#dispatchTransformedTouchEvent`
         MotionEvent transformed = event.copy();
-        transformed.offsetLocation(-view.getTop(), -view.getLeft());
+        transformed.offsetLocation(/* deltaX = */-view.getLeft(), /* deltaY = */ -view.getTop());
         return transformed;
     }
 
@@ -1474,4 +1523,9 @@
     }
 
     private abstract static class BooleanConsumer implements Consumer<Boolean> { }
+
+    private ShadeScrimShape createScrimShape(int left, int top, int right, int bottom) {
+        ShadeScrimBounds bounds = new ShadeScrimBounds(left, top, right, bottom);
+        return new ShadeScrimShape(bounds, 0, 0);
+    }
 }
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 bea027f..6e337ef 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
@@ -432,8 +432,7 @@
 
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
-        assertEquals(View.GONE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
     @Test
@@ -445,8 +444,7 @@
 
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
-        assertEquals(View.VISIBLE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.VISIBLE, getPrimaryOngoingActivityChipView().getVisibility());
         assertEquals(View.INVISIBLE, getNotificationAreaView().getVisibility());
     }
 
@@ -460,8 +458,7 @@
         fragment.disable(DEFAULT_DISPLAY,
                 StatusBarManager.DISABLE_NOTIFICATION_ICONS, 0, false);
 
-        assertEquals(View.GONE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
     @Test
@@ -474,8 +471,7 @@
 
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
-        assertEquals(View.GONE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
     @Test
@@ -487,22 +483,19 @@
         when(mOngoingCallController.hasOngoingCall()).thenReturn(true);
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
-        assertEquals(View.VISIBLE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.VISIBLE, getPrimaryOngoingActivityChipView().getVisibility());
 
         // Ongoing call ended
         when(mOngoingCallController.hasOngoingCall()).thenReturn(false);
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
-        assertEquals(View.GONE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
 
         // Ongoing call started
         when(mOngoingCallController.hasOngoingCall()).thenReturn(true);
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
-        assertEquals(View.VISIBLE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.VISIBLE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
     @Test
@@ -536,8 +529,7 @@
                 /* hasOngoingActivity= */ false, /* shouldAnimate= */ false);
 
         // THEN the old callback value is used, so the view is shown
-        assertEquals(View.VISIBLE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.VISIBLE, getPrimaryOngoingActivityChipView().getVisibility());
 
         // WHEN there's *no* ongoing call via old callback
         when(mOngoingCallController.hasOngoingCall()).thenReturn(false);
@@ -548,8 +540,7 @@
                 /* hasOngoingActivity= */ true, /* shouldAnimate= */ false);
 
         // THEN the old callback value is used, so the view is hidden
-        assertEquals(View.GONE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
     @Test
@@ -564,8 +555,7 @@
         mCollapsedStatusBarViewBinder.getListener().onOngoingActivityStatusChanged(
                 /* hasOngoingActivity= */ false, /* shouldAnimate= */ false);
 
-        assertEquals(View.GONE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
     @Test
@@ -576,8 +566,7 @@
         mCollapsedStatusBarViewBinder.getListener().onOngoingActivityStatusChanged(
                 /* hasOngoingActivity= */ true, /* shouldAnimate= */ false);
 
-        assertEquals(View.VISIBLE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.VISIBLE, getPrimaryOngoingActivityChipView().getVisibility());
         assertEquals(View.INVISIBLE, getNotificationAreaView().getVisibility());
     }
 
@@ -592,8 +581,7 @@
         fragment.disable(DEFAULT_DISPLAY,
                 StatusBarManager.DISABLE_NOTIFICATION_ICONS, 0, false);
 
-        assertEquals(View.GONE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
     @Test
@@ -607,8 +595,7 @@
 
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
-        assertEquals(View.GONE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
     @Test
@@ -620,15 +607,13 @@
         mCollapsedStatusBarViewBinder.getListener().onOngoingActivityStatusChanged(
                 /* hasOngoingActivity= */ true, /* shouldAnimate= */ false);
 
-        assertEquals(View.VISIBLE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.VISIBLE, getPrimaryOngoingActivityChipView().getVisibility());
 
         // Ongoing activity ended
         mCollapsedStatusBarViewBinder.getListener().onOngoingActivityStatusChanged(
                 /* hasOngoingActivity= */ false, /* shouldAnimate= */ false);
 
-        assertEquals(View.GONE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
     @Test
@@ -661,8 +646,7 @@
                 /* hasOngoingActivity= */ false, /* shouldAnimate= */ false);
 
         // THEN the new callback value is used, so the view is hidden
-        assertEquals(View.GONE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
 
         // WHEN there's *no* ongoing call via old callback
         when(mOngoingCallController.hasOngoingCall()).thenReturn(false);
@@ -673,8 +657,7 @@
                 /* hasOngoingActivity= */ true, /* shouldAnimate= */ false);
 
         // THEN the new callback value is used, so the view is shown
-        assertEquals(View.VISIBLE,
-                mFragment.getView().findViewById(R.id.ongoing_activity_chip).getVisibility());
+        assertEquals(View.VISIBLE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
     @Test
@@ -1023,4 +1006,8 @@
     private View getNotificationAreaView() {
         return mFragment.getView().findViewById(R.id.notificationIcons);
     }
+
+    private View getPrimaryOngoingActivityChipView() {
+        return mFragment.getView().findViewById(R.id.ongoing_activity_chip_primary);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
index 6de2caa..4b6e313 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
@@ -106,11 +106,7 @@
 class MobileConnectionsRepositoryTest : SysuiTestCase() {
 
     private val flags =
-        FakeFeatureFlagsClassic().also {
-            it.set(Flags.ROAMING_INDICATOR_VIA_DISPLAY_INFO, true)
-            it.set(Flags.INSTANT_TETHER, true)
-            it.set(Flags.WIFI_SECONDARY_NETWORKS, true)
-        }
+        FakeFeatureFlagsClassic().also { it.set(Flags.ROAMING_INDICATOR_VIA_DISPLAY_INFO, true) }
 
     private lateinit var connectionFactory: MobileConnectionRepositoryImpl.Factory
     private lateinit var carrierMergedFactory: CarrierMergedConnectionRepository.Factory
@@ -189,7 +185,6 @@
 
         wifiRepository =
             WifiRepositoryImpl(
-                flags,
                 testScope.backgroundScope,
                 mainExecutor,
                 testDispatcher,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt
index 60750cf..7ae6ea5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt
@@ -415,9 +415,9 @@
         }
 
     @Test
-    fun ongoingActivityChip_matchesViewModel() =
+    fun primaryOngoingActivityChip_matchesViewModel() =
         testScope.runTest {
-            val latest by collectLastValue(underTest.ongoingActivityChip)
+            val latest by collectLastValue(underTest.primaryOngoingActivityChip)
 
             kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt
index cefdf7e..e71f521 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt
@@ -28,7 +28,7 @@
 
     override val transitionFromLockscreenToDreamStartedEvent = MutableSharedFlow<Unit>()
 
-    override val ongoingActivityChip: MutableStateFlow<OngoingActivityChipModel> =
+    override val primaryOngoingActivityChip: MutableStateFlow<OngoingActivityChipModel> =
         MutableStateFlow(OngoingActivityChipModel.Hidden())
 
     override val isHomeStatusBarAllowedByScene = MutableStateFlow(false)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
index f8d50f5..b9c57d8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
@@ -25,8 +25,6 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.flags.FakeFeatureFlags
-import com.android.systemui.flags.Flags
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.statusbar.connectivity.WifiPickerTrackerFactory
@@ -76,7 +74,6 @@
     // inside each test case without needing to manually recreate the repository.
     private val underTest: WifiRepositoryImpl by lazy {
         WifiRepositoryImpl(
-            featureFlags,
             testScope.backgroundScope,
             executor,
             dispatcher,
@@ -89,7 +86,6 @@
 
     private val executor = FakeExecutor(FakeSystemClock())
     private val logger = LogBuffer("name", maxSize = 100, logcatEchoTracker = mock())
-    private val featureFlags = FakeFeatureFlags()
     private val tableLogger = mock<TableLogBuffer>()
     private val wifiManager =
         mock<WifiManager>().apply { whenever(this.maxSignalLevel).thenReturn(10) }
@@ -103,8 +99,6 @@
 
     @Before
     fun setUp() {
-        featureFlags.set(Flags.INSTANT_TETHER, false)
-        featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, false)
         whenever(wifiPickerTrackerFactory.create(any(), capture(callbackCaptor), any()))
             .thenReturn(wifiPickerTracker)
     }
@@ -394,7 +388,6 @@
     @Test
     fun wifiNetwork_notHotspot_none() =
         testScope.runTest {
-            featureFlags.set(Flags.INSTANT_TETHER, true)
             val latest by collectLastValue(underTest.wifiNetwork)
 
             val wifiEntry =
@@ -409,7 +402,6 @@
     @Test
     fun wifiNetwork_hotspot_unknown() =
         testScope.runTest {
-            featureFlags.set(Flags.INSTANT_TETHER, true)
             val latest by collectLastValue(underTest.wifiNetwork)
 
             val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_UNKNOWN)
@@ -423,7 +415,6 @@
     @Test
     fun wifiNetwork_hotspot_phone() =
         testScope.runTest {
-            featureFlags.set(Flags.INSTANT_TETHER, true)
             val latest by collectLastValue(underTest.wifiNetwork)
 
             val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_PHONE)
@@ -437,7 +428,6 @@
     @Test
     fun wifiNetwork_hotspot_tablet() =
         testScope.runTest {
-            featureFlags.set(Flags.INSTANT_TETHER, true)
             val latest by collectLastValue(underTest.wifiNetwork)
 
             val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_TABLET)
@@ -451,7 +441,6 @@
     @Test
     fun wifiNetwork_hotspot_laptop() =
         testScope.runTest {
-            featureFlags.set(Flags.INSTANT_TETHER, true)
             val latest by collectLastValue(underTest.wifiNetwork)
 
             val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_LAPTOP)
@@ -465,7 +454,6 @@
     @Test
     fun wifiNetwork_hotspot_watch() =
         testScope.runTest {
-            featureFlags.set(Flags.INSTANT_TETHER, true)
             val latest by collectLastValue(underTest.wifiNetwork)
 
             val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_WATCH)
@@ -479,7 +467,6 @@
     @Test
     fun wifiNetwork_hotspot_auto() =
         testScope.runTest {
-            featureFlags.set(Flags.INSTANT_TETHER, true)
             val latest by collectLastValue(underTest.wifiNetwork)
 
             val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_AUTO)
@@ -493,7 +480,6 @@
     @Test
     fun wifiNetwork_hotspot_invalid() =
         testScope.runTest {
-            featureFlags.set(Flags.INSTANT_TETHER, true)
             val latest by collectLastValue(underTest.wifiNetwork)
 
             val wifiEntry = createHotspotWithType(1234)
@@ -505,23 +491,6 @@
         }
 
     @Test
-    fun wifiNetwork_hotspot_flagOff_valueNotUsed() =
-        testScope.runTest {
-            // WHEN the flag is off
-            featureFlags.set(Flags.INSTANT_TETHER, false)
-
-            val latest by collectLastValue(underTest.wifiNetwork)
-
-            val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_WATCH)
-            whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
-            getCallback().onWifiEntriesChanged()
-
-            // THEN NONE is always used, even if the wifi entry does have a hotspot device type
-            assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
-                .isEqualTo(WifiNetworkModel.HotspotDeviceType.NONE)
-        }
-
-    @Test
     fun wifiNetwork_isCarrierMerged_flowHasCarrierMerged() =
         testScope.runTest {
             val latest by collectLastValue(underTest.wifiNetwork)
@@ -826,7 +795,6 @@
     @Test
     fun secondaryNetworks_activeEntriesEmpty_isEmpty() =
         testScope.runTest {
-            featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
             val latest by collectLastValue(underTest.secondaryNetworks)
 
             whenever(wifiPickerTracker.activeWifiEntries).thenReturn(listOf())
@@ -839,7 +807,6 @@
     @Test
     fun secondaryNetworks_oneActiveEntry_hasOne() =
         testScope.runTest {
-            featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
             val latest by collectLastValue(underTest.secondaryNetworks)
 
             val wifiEntry = mock<WifiEntry>()
@@ -853,7 +820,6 @@
     @Test
     fun secondaryNetworks_multipleActiveEntries_hasMultiple() =
         testScope.runTest {
-            featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
             val latest by collectLastValue(underTest.secondaryNetworks)
 
             val wifiEntry1 = mock<WifiEntry>()
@@ -868,7 +834,6 @@
     @Test
     fun secondaryNetworks_mapsToInactive() =
         testScope.runTest {
-            featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
             val latest by collectLastValue(underTest.secondaryNetworks)
 
             val inactiveEntry =
@@ -884,7 +849,6 @@
     @Test
     fun secondaryNetworks_mapsToActive() =
         testScope.runTest {
-            featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
             val latest by collectLastValue(underTest.secondaryNetworks)
 
             val activeEntry = mock<WifiEntry>().apply { whenever(this.level).thenReturn(2) }
@@ -900,7 +864,6 @@
     @Test
     fun secondaryNetworks_mapsToCarrierMerged() =
         testScope.runTest {
-            featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
             val latest by collectLastValue(underTest.secondaryNetworks)
 
             val carrierMergedEntry =
@@ -917,7 +880,6 @@
     @Test
     fun secondaryNetworks_mapsMultipleInOrder() =
         testScope.runTest {
-            featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
             val latest by collectLastValue(underTest.secondaryNetworks)
 
             val activeEntry = mock<WifiEntry>().apply { whenever(this.level).thenReturn(2) }
@@ -937,7 +899,6 @@
     @Test
     fun secondaryNetworks_filtersOutConnectedEntry() =
         testScope.runTest {
-            featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
             val latest by collectLastValue(underTest.secondaryNetworks)
 
             val connectedEntry = mock<WifiEntry>().apply { whenever(this.level).thenReturn(1) }
@@ -959,7 +920,6 @@
     @Test
     fun secondaryNetworks_noConnectedEntry_hasAllActiveEntries() =
         testScope.runTest {
-            featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
             val latest by collectLastValue(underTest.secondaryNetworks)
 
             val secondaryEntry1 = mock<WifiEntry>().apply { whenever(this.level).thenReturn(2) }
@@ -978,7 +938,6 @@
     @Test
     fun secondaryNetworks_filtersOutPrimaryNetwork() =
         testScope.runTest {
-            featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
             val latest by collectLastValue(underTest.secondaryNetworks)
 
             val primaryEntry =
@@ -1001,20 +960,6 @@
         }
 
     @Test
-    fun secondaryNetworks_flagOff_noNetworks() =
-        testScope.runTest {
-            featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, false)
-            val latest by collectLastValue(underTest.secondaryNetworks)
-
-            val wifiEntry = mock<WifiEntry>()
-            whenever(wifiPickerTracker.activeWifiEntries).thenReturn(listOf(wifiEntry))
-
-            getCallback().onWifiEntriesChanged()
-
-            assertThat(latest).isEmpty()
-        }
-
-    @Test
     fun isWifiConnectedWithValidSsid_inactiveNetwork_false() =
         testScope.runTest {
             collectLastValue(underTest.wifiNetwork)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt
index 171be97..649e4e8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt
@@ -33,16 +33,16 @@
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.StateFlow
 
-val Kosmos.bouncerSceneActionsViewModel by Fixture {
-    BouncerSceneActionsViewModel(
+val Kosmos.bouncerUserActionsViewModel by Fixture {
+    BouncerUserActionsViewModel(
         bouncerInteractor = bouncerInteractor,
     )
 }
 
-val Kosmos.bouncerSceneActionsViewModelFactory by Fixture {
-    object : BouncerSceneActionsViewModel.Factory {
-        override fun create(): BouncerSceneActionsViewModel {
-            return bouncerSceneActionsViewModel
+val Kosmos.bouncerUserActionsViewModelFactory by Fixture {
+    object : BouncerUserActionsViewModel.Factory {
+        override fun create(): BouncerUserActionsViewModel {
+            return bouncerUserActionsViewModel
         }
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneActionsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeUserActionsViewModelKosmos.kt
similarity index 85%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneActionsViewModelKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeUserActionsViewModelKosmos.kt
index 128a7fc..06592b1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneActionsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeUserActionsViewModelKosmos.kt
@@ -18,9 +18,9 @@
 
 import com.android.systemui.kosmos.Kosmos
 
-val Kosmos.quickSettingsShadeSceneActionsViewModel: QuickSettingsShadeSceneActionsViewModel by
+val Kosmos.quickSettingsShadeUserActionsViewModel: QuickSettingsShadeUserActionsViewModel by
     Kosmos.Fixture {
-        QuickSettingsShadeSceneActionsViewModel(
+        QuickSettingsShadeUserActionsViewModel(
             quickSettingsContainerViewModel = quickSettingsContainerViewModel,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeSceneActionsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeUserActionsViewModelKosmos.kt
similarity index 81%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeSceneActionsViewModelKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeUserActionsViewModelKosmos.kt
index f792ab9..6345c40 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeSceneActionsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeUserActionsViewModelKosmos.kt
@@ -18,7 +18,7 @@
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeSceneActionsViewModel
+import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeUserActionsViewModel
 
-val Kosmos.notificationsShadeSceneActionsViewModel:
-    NotificationsShadeSceneActionsViewModel by Fixture { NotificationsShadeSceneActionsViewModel() }
+val Kosmos.notificationsShadeUserActionsViewModel:
+    NotificationsShadeUserActionsViewModel by Fixture { NotificationsShadeUserActionsViewModel() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneActionsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelKosmos.kt
similarity index 89%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneActionsViewModelKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelKosmos.kt
index 2387aa8..48c5121 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneActionsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelKosmos.kt
@@ -21,8 +21,8 @@
 import com.android.systemui.qs.ui.adapter.qsSceneAdapter
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 
-val Kosmos.shadeSceneActionsViewModel: ShadeSceneActionsViewModel by Fixture {
-    ShadeSceneActionsViewModel(
+val Kosmos.shadeUserActionsViewModel: ShadeUserActionsViewModel by Fixture {
+    ShadeUserActionsViewModel(
         qsSceneAdapter = qsSceneAdapter,
         shadeInteractor = shadeInteractor,
     )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt
index 1fa6c3f..888351f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt
@@ -33,6 +33,12 @@
 
 class FakeAudioRepository : AudioRepository {
 
+    private val unMutableStreams =
+        setOf(
+            AudioManager.STREAM_VOICE_CALL,
+            AudioManager.STREAM_ALARM,
+        )
+
     private val mutableMode = MutableStateFlow(AudioManager.MODE_NORMAL)
     override val mode: StateFlow<Int> = mutableMode.asStateFlow()
 
@@ -73,7 +79,7 @@
                     volume = 0,
                     minVolume = 0,
                     maxVolume = 10,
-                    isAffectedByMute = false,
+                    isAffectedByMute = audioStream.value !in unMutableStreams,
                     isAffectedByRingerMode = false,
                     isMuted = false,
                 )
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index d16a665..1b2447e 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -26,6 +26,7 @@
 import android.annotation.NonNull;
 import android.content.Context;
 import android.graphics.Region;
+import android.hardware.input.InputManager;
 import android.os.Looper;
 import android.os.PowerManager;
 import android.os.SystemClock;
@@ -57,6 +58,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Objects;
 import java.util.StringJoiner;
 
 /**
@@ -748,6 +750,7 @@
 
         if ((mEnabledFeatures & FLAG_FEATURE_MOUSE_KEYS) != 0) {
             mMouseKeysInterceptor = new MouseKeysInterceptor(mAms,
+                    Objects.requireNonNull(mContext.getSystemService(InputManager.class)),
                     Looper.myLooper(),
                     Display.DEFAULT_DISPLAY);
             addFirstEventHandler(Display.DEFAULT_DISPLAY, mMouseKeysInterceptor);
diff --git a/services/accessibility/java/com/android/server/accessibility/MouseKeysInterceptor.java b/services/accessibility/java/com/android/server/accessibility/MouseKeysInterceptor.java
index 2ce5c2b..54368ca 100644
--- a/services/accessibility/java/com/android/server/accessibility/MouseKeysInterceptor.java
+++ b/services/accessibility/java/com/android/server/accessibility/MouseKeysInterceptor.java
@@ -23,6 +23,7 @@
 import android.annotation.RequiresPermission;
 import android.companion.virtual.VirtualDeviceManager;
 import android.companion.virtual.VirtualDeviceParams;
+import android.hardware.input.InputManager;
 import android.hardware.input.VirtualMouse;
 import android.hardware.input.VirtualMouseButtonEvent;
 import android.hardware.input.VirtualMouseConfig;
@@ -34,8 +35,11 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.view.InputDevice;
 import android.view.KeyEvent;
 
+import androidx.annotation.VisibleForTesting;
+
 import com.android.server.LocalServices;
 import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
 
@@ -60,7 +64,7 @@
  * mouse keys of each physical keyboard will control a single (global) mouse pointer.
  */
 public class MouseKeysInterceptor extends BaseEventStreamTransformation
-        implements Handler.Callback {
+        implements Handler.Callback, InputManager.InputDeviceListener {
     private static final String LOG_TAG = "MouseKeysInterceptor";
 
     // To enable these logs, run: 'adb shell setprop log.tag.MouseKeysInterceptor DEBUG'
@@ -77,10 +81,19 @@
 
     private final AccessibilityManagerService mAms;
     private final Handler mHandler;
+    private final InputManager mInputManager;
 
     /** Thread to wait for virtual mouse creation to complete */
     private final Thread mCreateVirtualMouseThread;
 
+    /**
+     * Map of device IDs to a map of key codes to their corresponding {@link MouseKeyEvent} values.
+     * To ensure thread safety for the map, all access and modification of the map
+     * should happen on the same thread, i.e., on the handler thread.
+     */
+    private final SparseArray<SparseArray<MouseKeyEvent>> mDeviceKeyCodeMap =
+            new SparseArray<>();
+
     VirtualDeviceManager.VirtualDevice mVirtualDevice = null;
 
     private VirtualMouse mVirtualMouse = null;
@@ -102,6 +115,21 @@
     /** Whether scroll toggle is on */
     private boolean mScrollToggleOn = false;
 
+    /** The ID of the input device that is currently active */
+    private int mActiveInputDeviceId = 0;
+
+    /**
+     * Enum representing different types of mouse key events, each associated with a specific
+     * key code.
+     *
+     * <p> These events correspond to various mouse actions such as directional movements,
+     * clicks, and scrolls, mapped to specific keys on the keyboard.
+     * The key codes here are the QWERTY key codes, and should be accessed via
+     * {@link MouseKeyEvent#getKeyCode(InputDevice)}
+     * so that it is mapped to the equivalent key on the keyboard layout of the keyboard device
+     * that is actually in use.
+     * </p>
+     */
     public enum MouseKeyEvent {
         DIAGONAL_UP_LEFT_MOVE(KeyEvent.KEYCODE_7),
         UP_MOVE_OR_SCROLL(KeyEvent.KEYCODE_8),
@@ -117,34 +145,64 @@
         RELEASE(KeyEvent.KEYCODE_COMMA),
         SCROLL_TOGGLE(KeyEvent.KEYCODE_PERIOD);
 
-        private final int mKeyCode;
+        private final int mLocationKeyCode;
         MouseKeyEvent(int enumValue) {
-            mKeyCode = enumValue;
+            mLocationKeyCode = enumValue;
         }
 
-        private static final SparseArray<MouseKeyEvent> VALUE_TO_ENUM_MAP = new SparseArray<>();
-
-        static {
-            for (MouseKeyEvent type : MouseKeyEvent.values()) {
-                VALUE_TO_ENUM_MAP.put(type.mKeyCode, type);
-            }
-        }
-
+        @VisibleForTesting
         public final int getKeyCodeValue() {
-            return mKeyCode;
+            return mLocationKeyCode;
         }
 
         /**
-         * Convert int value of the key code to corresponding MouseEvent enum. If no matching
-         * value is found, this will return {@code null}.
+         * Get the key code associated with the given MouseKeyEvent for the given keyboard
+         * input device, taking into account its layout.
+         * The default is to return the keycode for the default layout (QWERTY).
+         * We check if the input device has been generated using {@link InputDevice#getGeneration()}
+         * to test with the default {@link MouseKeyEvent} values in the unit tests.
+         */
+        public int getKeyCode(InputDevice inputDevice) {
+            if (inputDevice.getGeneration() == -1) {
+                return mLocationKeyCode;
+            }
+            return inputDevice.getKeyCodeForKeyLocation(mLocationKeyCode);
+        }
+
+        /**
+         * Convert int value of the key code to corresponding {@link MouseKeyEvent}
+         * enum for a particular device ID.
+         * If no matching value is found, this will return {@code null}.
          */
         @Nullable
-        public static MouseKeyEvent from(int value) {
-            return VALUE_TO_ENUM_MAP.get(value);
+        public static MouseKeyEvent from(int keyCode, int deviceId,
+                SparseArray<SparseArray<MouseKeyEvent>> deviceKeyCodeMap) {
+            SparseArray<MouseKeyEvent> keyCodeToEnumMap = deviceKeyCodeMap.get(deviceId);
+            if (keyCodeToEnumMap != null) {
+                return keyCodeToEnumMap.get(keyCode);
+            }
+            return null;
         }
     }
 
     /**
+     * Create a map of key codes to their corresponding {@link MouseKeyEvent} values
+     * for a specific input device.
+     * The key for {@code mDeviceKeyCodeMap} is the deviceId.
+     * The key for {@code keyCodeToEnumMap} is the keycode for each
+     * {@link MouseKeyEvent} according to the keyboard layout of the input device.
+     */
+    public void initializeDeviceToEnumMap(InputDevice inputDevice) {
+        int deviceId = inputDevice.getId();
+        SparseArray<MouseKeyEvent> keyCodeToEnumMap = new SparseArray<>();
+        for (MouseKeyEvent mouseKeyEventType : MouseKeyEvent.values()) {
+            int keyCode = mouseKeyEventType.getKeyCode(inputDevice);
+            keyCodeToEnumMap.put(keyCode, mouseKeyEventType);
+        }
+        mDeviceKeyCodeMap.put(deviceId, keyCodeToEnumMap);
+    }
+
+    /**
      * Construct a new MouseKeysInterceptor.
      *
      * @param service The service to notify of key events
@@ -152,8 +210,10 @@
      * @param displayId Display ID to send mouse events to
      */
     @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
-    public MouseKeysInterceptor(AccessibilityManagerService service, Looper looper, int displayId) {
+    public MouseKeysInterceptor(AccessibilityManagerService service,
+            InputManager inputManager, Looper looper, int displayId) {
         mAms = service;
+        mInputManager = inputManager;
         mHandler = new Handler(looper, this);
         // Create the virtual mouse on a separate thread since virtual device creation
         // should happen on an auxiliary thread, and not from the handler's thread.
@@ -163,6 +223,9 @@
             mVirtualMouse = createVirtualMouse(displayId);
         });
         mCreateVirtualMouseThread.start();
+        // Register an input device listener to watch when input devices are
+        // added, removed or reconfigured.
+        mInputManager.registerInputDeviceListener(this, mHandler);
     }
 
     /**
@@ -215,7 +278,8 @@
      */
     @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
     private void performMouseScrollAction(int keyCode) {
-        MouseKeyEvent mouseKeyEvent = MouseKeyEvent.from(keyCode);
+        MouseKeyEvent mouseKeyEvent = MouseKeyEvent.from(
+                keyCode, mActiveInputDeviceId, mDeviceKeyCodeMap);
         float y = switch (mouseKeyEvent) {
             case UP_MOVE_OR_SCROLL -> 1.0f;
             case DOWN_MOVE_OR_SCROLL -> -1.0f;
@@ -247,15 +311,18 @@
      */
     @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
     private void performMouseButtonAction(int keyCode) {
-        MouseKeyEvent mouseKeyEvent = MouseKeyEvent.from(keyCode);
+        MouseKeyEvent mouseKeyEvent = MouseKeyEvent.from(
+                keyCode, mActiveInputDeviceId, mDeviceKeyCodeMap);
         int buttonCode = switch (mouseKeyEvent) {
             case LEFT_CLICK -> VirtualMouseButtonEvent.BUTTON_PRIMARY;
             case RIGHT_CLICK -> VirtualMouseButtonEvent.BUTTON_SECONDARY;
             default -> VirtualMouseButtonEvent.BUTTON_UNKNOWN;
         };
         if (buttonCode != VirtualMouseButtonEvent.BUTTON_UNKNOWN) {
-            sendVirtualMouseButtonEvent(buttonCode, VirtualMouseButtonEvent.ACTION_BUTTON_PRESS);
-            sendVirtualMouseButtonEvent(buttonCode, VirtualMouseButtonEvent.ACTION_BUTTON_RELEASE);
+            sendVirtualMouseButtonEvent(buttonCode,
+                    VirtualMouseButtonEvent.ACTION_BUTTON_PRESS);
+            sendVirtualMouseButtonEvent(buttonCode,
+                    VirtualMouseButtonEvent.ACTION_BUTTON_RELEASE);
         }
         if (DEBUG) {
             if (buttonCode == VirtualMouseButtonEvent.BUTTON_UNKNOWN) {
@@ -293,7 +360,9 @@
     private void performMousePointerAction(int keyCode) {
         float x = 0f;
         float y = 0f;
-        MouseKeyEvent mouseKeyEvent = MouseKeyEvent.from(keyCode);
+        MouseKeyEvent mouseKeyEvent = MouseKeyEvent.from(
+                keyCode, mActiveInputDeviceId, mDeviceKeyCodeMap);
+
         switch (mouseKeyEvent) {
             case DIAGONAL_DOWN_LEFT_MOVE -> {
                 x = -MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
@@ -339,18 +408,19 @@
         }
     }
 
-    private boolean isMouseKey(int keyCode) {
-        return MouseKeyEvent.VALUE_TO_ENUM_MAP.contains(keyCode);
+    private boolean isMouseKey(int keyCode, int deviceId) {
+        SparseArray<MouseKeyEvent> keyCodeToEnumMap = mDeviceKeyCodeMap.get(deviceId);
+        return keyCodeToEnumMap.contains(keyCode);
     }
 
-    private boolean isMouseButtonKey(int keyCode) {
-        return keyCode == MouseKeyEvent.LEFT_CLICK.getKeyCodeValue()
-                || keyCode == MouseKeyEvent.RIGHT_CLICK.getKeyCodeValue();
+    private boolean isMouseButtonKey(int keyCode, InputDevice inputDevice) {
+        return keyCode == MouseKeyEvent.LEFT_CLICK.getKeyCode(inputDevice)
+                || keyCode == MouseKeyEvent.RIGHT_CLICK.getKeyCode(inputDevice);
     }
 
-    private boolean isMouseScrollKey(int keyCode) {
-        return keyCode == MouseKeyEvent.UP_MOVE_OR_SCROLL.getKeyCodeValue()
-                || keyCode == MouseKeyEvent.DOWN_MOVE_OR_SCROLL.getKeyCodeValue();
+    private boolean isMouseScrollKey(int keyCode, InputDevice inputDevice) {
+        return keyCode == MouseKeyEvent.UP_MOVE_OR_SCROLL.getKeyCode(inputDevice)
+                || keyCode == MouseKeyEvent.DOWN_MOVE_OR_SCROLL.getKeyCode(inputDevice);
     }
 
     /**
@@ -373,7 +443,7 @@
     }
 
     /**
-     * Handles key events and forwards mouse key events to the virtual mouse.
+     * Handles key events and forwards mouse key events to the virtual mouse on the handler thread.
      *
      * @param event The key event to handle.
      * @param policyFlags The policy flags associated with the key event.
@@ -385,31 +455,45 @@
             mAms.getTraceManager().logTrace(LOG_TAG + ".onKeyEvent",
                     FLAGS_INPUT_FILTER, "event=" + event + ";policyFlags=" + policyFlags);
         }
+
+        mHandler.post(() -> {
+            onKeyEventInternal(event, policyFlags);
+        });
+    }
+
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    private void onKeyEventInternal(KeyEvent event, int policyFlags) {
         boolean isDown = event.getAction() == KeyEvent.ACTION_DOWN;
         int keyCode = event.getKeyCode();
+        mActiveInputDeviceId = event.getDeviceId();
+        InputDevice inputDevice = mInputManager.getInputDevice(mActiveInputDeviceId);
 
-        if (!isMouseKey(keyCode)) {
+        if (!mDeviceKeyCodeMap.contains(mActiveInputDeviceId)) {
+            initializeDeviceToEnumMap(inputDevice);
+        }
+
+        if (!isMouseKey(keyCode, mActiveInputDeviceId)) {
             // Pass non-mouse key events to the next handler
             super.onKeyEvent(event, policyFlags);
         } else if (isDown) {
-            if (keyCode == MouseKeyEvent.SCROLL_TOGGLE.getKeyCodeValue()) {
+            if (keyCode == MouseKeyEvent.SCROLL_TOGGLE.getKeyCode(inputDevice)) {
                 mScrollToggleOn = !mScrollToggleOn;
                 if (DEBUG) {
                     Slog.d(LOG_TAG, "Scroll toggle " + (mScrollToggleOn ? "ON" : "OFF"));
                 }
-            } else if (keyCode == MouseKeyEvent.HOLD.getKeyCodeValue()) {
+            } else if (keyCode == MouseKeyEvent.HOLD.getKeyCode(inputDevice)) {
                 sendVirtualMouseButtonEvent(
                         VirtualMouseButtonEvent.BUTTON_PRIMARY,
                         VirtualMouseButtonEvent.ACTION_BUTTON_PRESS
                 );
-            } else if (keyCode == MouseKeyEvent.RELEASE.getKeyCodeValue()) {
+            } else if (keyCode == MouseKeyEvent.RELEASE.getKeyCode(inputDevice)) {
                 sendVirtualMouseButtonEvent(
                         VirtualMouseButtonEvent.BUTTON_PRIMARY,
                         VirtualMouseButtonEvent.ACTION_BUTTON_RELEASE
                 );
-            } else if (isMouseButtonKey(keyCode)) {
+            } else if (isMouseButtonKey(keyCode, inputDevice)) {
                 performMouseButtonAction(keyCode);
-            } else if (mScrollToggleOn && isMouseScrollKey(keyCode)) {
+            } else if (mScrollToggleOn && isMouseScrollKey(keyCode, inputDevice)) {
                 // If the scroll key is pressed down and no other key is active,
                 // set it as the active key and send a message to scroll the pointer
                 if (mActiveScrollKey == KEY_NOT_SET) {
@@ -439,7 +523,8 @@
                 mHandler.removeMessages(MESSAGE_SCROLL_MOUSE_POINTER);
             } else {
                 Slog.i(LOG_TAG, "Dropping event with key code: '" + keyCode
-                        + "', with no matching down event from deviceId = " + event.getDeviceId());
+                        + "', with no matching down event from deviceId = "
+                        + event.getDeviceId());
             }
         }
     }
@@ -503,12 +588,40 @@
     @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
     @Override
     public void onDestroy() {
-        // Clear mouse state
-        mActiveMoveKey = KEY_NOT_SET;
-        mActiveScrollKey = KEY_NOT_SET;
-        mLastTimeKeyActionPerformed = 0;
+        mHandler.post(() -> {
+            // Clear mouse state
+            mActiveMoveKey = KEY_NOT_SET;
+            mActiveScrollKey = KEY_NOT_SET;
+            mLastTimeKeyActionPerformed = 0;
+            mDeviceKeyCodeMap.clear();
+        });
 
         mHandler.removeCallbacksAndMessages(null);
         mVirtualDevice.close();
     }
+
+    @Override
+    public void onInputDeviceAdded(int deviceId) {
+    }
+
+    @Override
+    public void onInputDeviceRemoved(int deviceId) {
+        mDeviceKeyCodeMap.remove(deviceId);
+    }
+
+    /**
+     * The user can change the keyboard layout from settings at anytime, which would change
+     * key character map for that device. Hence, we should use this callback to
+     * update the key code to enum mapping if there is a change in the physical keyboard detected.
+     *
+     * @param deviceId The id of the input device that changed.
+     */
+    @Override
+    public void onInputDeviceChanged(int deviceId) {
+        InputDevice inputDevice = mInputManager.getInputDevice(deviceId);
+        // Update the enum mapping only if input device that changed is a keyboard
+        if (inputDevice.isFullKeyboard() && !mDeviceKeyCodeMap.contains(deviceId)) {
+            initializeDeviceToEnumMap(inputDevice);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e13b0a4..3c57476 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -299,7 +299,6 @@
 import android.content.pm.UserInfo;
 import android.content.pm.UserProperties;
 import android.content.pm.VersionedPackage;
-import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
@@ -2971,10 +2970,6 @@
         }
     }
 
-    CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
-        return mAtmInternal.compatibilityInfoForPackage(ai);
-    }
-
     /**
      * Enforces that the uid that calls a method is not an
      * {@link UserHandle#isIsolated(int) isolated} uid.
@@ -4635,7 +4630,6 @@
             ProtoLog.v(WM_DEBUG_CONFIGURATION, "Binding proc %s with config %s",
                     processName, app.getWindowProcessController().getConfiguration());
             ApplicationInfo appInfo = instr != null ? instr.mTargetInfo : app.info;
-            app.setCompat(compatibilityInfoForPackage(appInfo));
 
             ProfilerInfo profilerInfo = mAppProfiler.setupProfilerInfoLocked(thread, app, instr);
 
@@ -4674,7 +4668,9 @@
             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
             bindApplicationTimeMillis = SystemClock.uptimeMillis();
             bindApplicationTimeNanos = SystemClock.uptimeNanos();
-            mAtmInternal.preBindApplication(app.getWindowProcessController());
+            final ActivityTaskManagerInternal.PreBindInfo preBindInfo =
+                    mAtmInternal.preBindApplication(app.getWindowProcessController(), appInfo);
+            app.setCompat(preBindInfo.compatibilityInfo);
             final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
             if (mPlatformCompat != null) {
                 mPlatformCompat.resetReporting(app.info);
@@ -4716,7 +4712,7 @@
                         enableTrackAllocation,
                         isRestrictedBackupMode || !normalMode,
                         app.isPersistent(),
-                        new Configuration(app.getWindowProcessController().getConfiguration()),
+                        preBindInfo.configuration,
                         app.getCompat(),
                         getCommonServicesLocked(app.isolated),
                         mCoreSettingsObserver.getCoreSettingsLocked(),
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 0e266f5..7e3f613 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1126,26 +1126,31 @@
         final int numLru = lruList.size();
         if (mConstants.USE_TIERED_CACHED_ADJ) {
             final long now = mInjector.getUptimeMillis();
+            int uiTargetAdj = 10;
             for (int i = numLru - 1; i >= 0; i--) {
                 ProcessRecord app = lruList.get(i);
                 final ProcessStateRecord state = app.mState;
                 final ProcessCachedOptimizerRecord opt = app.mOptRecord;
-                if (!app.isKilledByAm() && app.getThread() != null && state.getCurAdj()
-                        >= UNKNOWN_ADJ) {
+                if (!app.isKilledByAm() && app.getThread() != null
+                        && (state.getCurAdj() >= UNKNOWN_ADJ
+                            || (state.hasShownUi() && state.getCurAdj() >= CACHED_APP_MIN_ADJ))) {
                     final ProcessServiceRecord psr = app.mServices;
                     int targetAdj = CACHED_APP_MIN_ADJ;
 
                     if (opt != null && opt.isFreezeExempt()) {
                         // BIND_WAIVE_PRIORITY and the like get oom_adj 900
                         targetAdj += 0;
+                    } else if (state.hasShownUi() && uiTargetAdj < 15) {
+                        // The most recent 5 apps that have shown UI get 910-914
+                        targetAdj += uiTargetAdj++;
                     } else if ((state.getSetAdj() >= CACHED_APP_MIN_ADJ)
                             && (state.getLastStateTime()
                                     + mConstants.TIERED_CACHED_ADJ_DECAY_TIME) < now) {
                         // Older cached apps get 950
                         targetAdj += 50;
                     } else {
-                        // Newer cached apps get 910
-                        targetAdj += 10;
+                        // Newer cached apps get 920
+                        targetAdj += 20;
                     }
                     state.setCurRawAdj(targetAdj);
                     state.setCurAdj(psr.modifyRawOomAdj(targetAdj));
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index bdba6bc..b186eaa 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -1978,6 +1978,7 @@
                 boolean userSwitchUiEnabled;
                 synchronized (mLock) {
                     mCurrentUserId = userId;
+                    ActivityManager.invalidateGetCurrentUserIdCache();
                     userSwitchUiEnabled = mUserSwitchUiEnabled;
                 }
                 mInjector.updateUserConfiguration();
@@ -2239,6 +2240,7 @@
                 return true;
             }
             mTargetUserId = targetUserId;
+            ActivityManager.invalidateGetCurrentUserIdCache();
             userSwitchUiEnabled = mUserSwitchUiEnabled;
         }
         if (userSwitchUiEnabled) {
@@ -2316,6 +2318,7 @@
         synchronized (mLock) {
             nextUserId = ObjectUtils.getOrElse(mPendingTargetUserIds.poll(), UserHandle.USER_NULL);
             mTargetUserId = UserHandle.USER_NULL;
+            ActivityManager.invalidateGetCurrentUserIdCache();
         }
         if (nextUserId != UserHandle.USER_NULL) {
             switchUser(nextUserId);
@@ -3021,6 +3024,9 @@
         mInjector.getUserManagerInternal().addUserLifecycleListener(mUserLifecycleListener);
         updateProfileRelatedCaches();
         mInjector.reportCurWakefulnessUsageEvent();
+
+        // IpcDataCache must be invalidated before it starts caching.
+        ActivityManager.invalidateGetCurrentUserIdCache();
     }
 
     // TODO(b/266158156): remove this method if initial system user boot logic is refactored?
@@ -3184,6 +3190,9 @@
 
     @GuardedBy("mLock")
     private int getCurrentOrTargetUserIdLU() {
+        // Note: this result is currently cached by ActivityManager.getCurrentUser() - changes to
+        // the logic here may require updating how the cache is invalidated.
+        // See ActivityManager.invalidateGetCurrentUserIdCache() for more details.
         return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
     }
 
diff --git a/services/core/java/com/android/server/biometrics/PreAuthInfo.java b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
index eaf4f81..ac3c028 100644
--- a/services/core/java/com/android/server/biometrics/PreAuthInfo.java
+++ b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
@@ -120,7 +120,9 @@
                         userId), trustManager)) {
             isMandatoryBiometricsAuthentication = true;
             promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG);
-            promptInfo.setNegativeButtonText(context.getString(R.string.cancel));
+            if (promptInfo.getNegativeButtonText() == null) {
+                promptInfo.setNegativeButtonText(context.getString(R.string.cancel));
+            }
         }
 
         final boolean biometricRequested = Utils.isBiometricRequested(promptInfo);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 99ad65d..2b732ea 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -269,6 +269,7 @@
 
     private final Context mContext;
     private final DisplayManagerHandler mHandler;
+    private final HandlerExecutor mHandlerExecutor;
     private final Handler mUiHandler;
     private final DisplayModeDirector mDisplayModeDirector;
     private final ExternalDisplayPolicy mExternalDisplayPolicy;
@@ -315,6 +316,7 @@
     public boolean mSafeMode;
 
     // All callback records indexed by calling process id.
+    @GuardedBy("mSyncRoot")
     private final SparseArray<CallbackRecord> mCallbacks = new SparseArray<>();
 
     /**
@@ -354,7 +356,7 @@
             new CopyOnWriteArrayList<>();
 
     /** All {@link DisplayPowerController}s indexed by {@link LogicalDisplay} ID. */
-    private final SparseArray<DisplayPowerControllerInterface> mDisplayPowerControllers =
+    private final SparseArray<DisplayPowerController> mDisplayPowerControllers =
             new SparseArray<>();
 
     /** {@link DisplayBlanker} used by all {@link DisplayPowerController}s. */
@@ -602,6 +604,7 @@
         mContext = context;
         mFlags = injector.getFlags();
         mHandler = new DisplayManagerHandler(displayThreadLooper);
+        mHandlerExecutor = new HandlerExecutor(mHandler);
         mUiHandler = UiThread.getHandler();
         mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore);
         mLogicalDisplayMapper = new LogicalDisplayMapper(mContext,
@@ -726,7 +729,7 @@
                 if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) {
                     return;
                 }
-                final DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(
+                final DisplayPowerController dpc = mDisplayPowerControllers.get(
                         logicalDisplay.getDisplayIdLocked());
                 if (dpc == null) {
                     return;
@@ -760,12 +763,13 @@
             mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
             mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
             mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
+
             ActivityManager activityManager = mContext.getSystemService(ActivityManager.class);
             activityManager.addOnUidImportanceListener(mUidImportanceListener, IMPORTANCE_CACHED);
 
             mDeviceStateManager = LocalServices.getService(DeviceStateManagerInternal.class);
             mContext.getSystemService(DeviceStateManager.class).registerCallback(
-                    new HandlerExecutor(mHandler), new DeviceStateListener());
+                    mHandlerExecutor, new DeviceStateListener());
 
             mLogicalDisplayMapper.onWindowManagerReady();
             scheduleTraversalLocked(false);
@@ -1019,6 +1023,10 @@
     private class UidImportanceListener implements ActivityManager.OnUidImportanceListener {
         @Override
         public void onUidImportance(int uid, int importance) {
+          onUidImportanceInternal(uid, importance);
+        }
+
+        private void onUidImportanceInternal(int uid, int importance) {
             synchronized (mPendingCallbackSelfLocked) {
                 if (importance >= IMPORTANCE_GONE) {
                     // Clean up as the app is already gone
@@ -2058,7 +2066,7 @@
             configurePreferredDisplayModeLocked(display);
         }
 
-        DisplayPowerControllerInterface dpc = addDisplayPowerControllerLocked(display);
+        DisplayPowerController dpc = addDisplayPowerControllerLocked(display);
         if (dpc != null) {
             final int leadDisplayId = display.getLeadDisplayIdLocked();
             updateDisplayPowerControllerLeaderLocked(dpc, leadDisplayId);
@@ -2067,7 +2075,7 @@
             // that the follower display was added before the lead display.
             mLogicalDisplayMapper.forEachLocked(d -> {
                 if (d.getLeadDisplayIdLocked() == displayId) {
-                    DisplayPowerControllerInterface followerDpc =
+                    DisplayPowerController followerDpc =
                             mDisplayPowerControllers.get(d.getDisplayIdLocked());
                     if (followerDpc != null) {
                         updateDisplayPowerControllerLeaderLocked(followerDpc, displayId);
@@ -2151,7 +2159,7 @@
         scheduleTraversalLocked(false);
         mPersistentDataStore.saveIfNeeded();
 
-        DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId);
+        DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
         if (dpc != null) {
             final int leadDisplayId = display.getLeadDisplayIdLocked();
             updateDisplayPowerControllerLeaderLocked(dpc, leadDisplayId);
@@ -2165,7 +2173,7 @@
     }
 
     private void updateDisplayPowerControllerLeaderLocked(
-            @NonNull DisplayPowerControllerInterface dpc, int leadDisplayId) {
+            @NonNull DisplayPowerController dpc, int leadDisplayId) {
         if (dpc.getLeadDisplayId() == leadDisplayId) {
             // Lead display hasn't changed, nothing to do.
             return;
@@ -2174,7 +2182,7 @@
         // If it has changed, then we need to unregister from the previous leader if there was one.
         final int prevLeaderId = dpc.getLeadDisplayId();
         if (prevLeaderId != Layout.NO_LEAD_DISPLAY) {
-            final DisplayPowerControllerInterface prevLeader =
+            final DisplayPowerController prevLeader =
                     mDisplayPowerControllers.get(prevLeaderId);
             if (prevLeader != null) {
                 prevLeader.removeDisplayBrightnessFollower(dpc);
@@ -2183,7 +2191,7 @@
 
         // And then, if it's following, register it with the new one.
         if (leadDisplayId != Layout.NO_LEAD_DISPLAY) {
-            final DisplayPowerControllerInterface newLeader =
+            final DisplayPowerController newLeader =
                     mDisplayPowerControllers.get(leadDisplayId);
             if (newLeader != null) {
                 newLeader.addDisplayBrightnessFollower(dpc);
@@ -2224,7 +2232,7 @@
     private void releaseDisplayAndEmitEvent(LogicalDisplay display, int event) {
         final int displayId = display.getDisplayIdLocked();
 
-        final DisplayPowerControllerInterface dpc =
+        final DisplayPowerController dpc =
                 mDisplayPowerControllers.removeReturnOld(displayId);
         if (dpc != null) {
             updateDisplayPowerControllerLeaderLocked(dpc, Layout.NO_LEAD_DISPLAY);
@@ -2271,7 +2279,7 @@
 
     private void handleLogicalDisplayDeviceStateTransitionLocked(@NonNull LogicalDisplay display) {
         final int displayId = display.getDisplayIdLocked();
-        final DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId);
+        final DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
         if (dpc != null) {
             final int leadDisplayId = display.getLeadDisplayIdLocked();
             updateDisplayPowerControllerLeaderLocked(dpc, leadDisplayId);
@@ -2692,14 +2700,14 @@
             if (userId != mCurrentUserId) {
                 return;
             }
-            DisplayPowerControllerInterface dpc = getDpcFromUniqueIdLocked(uniqueId);
+            DisplayPowerController dpc = getDpcFromUniqueIdLocked(uniqueId);
             if (dpc != null) {
                 dpc.setBrightnessConfiguration(c, /* shouldResetShortTermModel= */ true);
             }
         }
     }
 
-    private DisplayPowerControllerInterface getDpcFromUniqueIdLocked(String uniqueId) {
+    private DisplayPowerController getDpcFromUniqueIdLocked(String uniqueId) {
         final DisplayDevice displayDevice = mDisplayDeviceRepo.getByUniqueIdLocked(uniqueId);
         final LogicalDisplay logicalDisplay = mLogicalDisplayMapper.getDisplayLocked(displayDevice);
         if (logicalDisplay != null) {
@@ -2740,7 +2748,7 @@
                 final BrightnessConfiguration config =
                         getBrightnessConfigForDisplayWithPdsFallbackLocked(uniqueId, userSerial);
                 if (config != null) {
-                    final DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(
+                    final DisplayPowerController dpc = mDisplayPowerControllers.get(
                             logicalDisplay.getDisplayIdLocked());
                     if (dpc != null) {
                         dpc.setBrightnessConfiguration(config,
@@ -2987,7 +2995,7 @@
 
     void setAutoBrightnessLoggingEnabled(boolean enabled) {
         synchronized (mSyncRoot) {
-            final DisplayPowerControllerInterface displayPowerController =
+            final DisplayPowerController displayPowerController =
                     mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY);
             if (displayPowerController != null) {
                 displayPowerController.setAutoBrightnessLoggingEnabled(enabled);
@@ -2997,7 +3005,7 @@
 
     void setDisplayWhiteBalanceLoggingEnabled(boolean enabled) {
         synchronized (mSyncRoot) {
-            final DisplayPowerControllerInterface displayPowerController =
+            final DisplayPowerController displayPowerController =
                     mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY);
             if (displayPowerController != null) {
                 displayPowerController.setDisplayWhiteBalanceLoggingEnabled(enabled);
@@ -3023,7 +3031,7 @@
 
     void setAmbientColorTemperatureOverride(float cct) {
         synchronized (mSyncRoot) {
-            final DisplayPowerControllerInterface displayPowerController =
+            final DisplayPowerController displayPowerController =
                     mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY);
             if (displayPowerController != null) {
                 displayPowerController.setAmbientColorTemperatureOverride(cct);
@@ -3033,7 +3041,7 @@
 
     void setDockedAndIdleEnabled(boolean enabled, int displayId) {
         synchronized (mSyncRoot) {
-            final DisplayPowerControllerInterface displayPowerController =
+            final DisplayPowerController displayPowerController =
                     mDisplayPowerControllers.get(displayId);
             if (displayPowerController != null) {
                 displayPowerController.setAutomaticScreenBrightnessMode(enabled
@@ -3232,36 +3240,40 @@
         // After releasing the lock, send the notifications out.
         for (int i = 0; i < mTempCallbacks.size(); i++) {
             CallbackRecord callbackRecord = mTempCallbacks.get(i);
-            final int uid = callbackRecord.mUid;
-            final int pid = callbackRecord.mPid;
-            if (isUidCached(uid)) {
-                // For cached apps, save the pending event until it becomes non-cached
-                synchronized (mPendingCallbackSelfLocked) {
-                    SparseArray<PendingCallback> pendingCallbacks = mPendingCallbackSelfLocked.get(
-                            uid);
-                    if (extraLogging(callbackRecord.mPackageName)) {
-                        Slog.i(TAG, "Uid is cached: " + uid
-                                + ", pendingCallbacks: " + pendingCallbacks);
-                    }
-                    if (pendingCallbacks == null) {
-                        pendingCallbacks = new SparseArray<>();
-                        mPendingCallbackSelfLocked.put(uid, pendingCallbacks);
-                    }
-                    PendingCallback pendingCallback = pendingCallbacks.get(pid);
-                    if (pendingCallback == null) {
-                        pendingCallbacks.put(pid,
-                                new PendingCallback(callbackRecord, displayId, event));
-                    } else {
-                        pendingCallback.addDisplayEvent(displayId, event);
-                    }
-                }
-            } else {
-                callbackRecord.notifyDisplayEventAsync(displayId, event);
-            }
+            deliverEventInternal(callbackRecord, displayId, event);
         }
         mTempCallbacks.clear();
     }
 
+    private void deliverEventInternal(CallbackRecord callbackRecord, int displayId, int event) {
+        final int uid = callbackRecord.mUid;
+        final int pid = callbackRecord.mPid;
+        if (isUidCached(uid)) {
+            // For cached apps, save the pending event until it becomes non-cached
+            synchronized (mPendingCallbackSelfLocked) {
+                SparseArray<PendingCallback> pendingCallbacks = mPendingCallbackSelfLocked.get(
+                    uid);
+                if (extraLogging(callbackRecord.mPackageName)) {
+                    Slog.i(TAG, "Uid is cached: " + uid
+                            + ", pendingCallbacks: " + pendingCallbacks);
+                }
+                if (pendingCallbacks == null) {
+                    pendingCallbacks = new SparseArray<>();
+                    mPendingCallbackSelfLocked.put(uid, pendingCallbacks);
+                }
+                PendingCallback pendingCallback = pendingCallbacks.get(pid);
+                if (pendingCallback == null) {
+                    pendingCallbacks.put(pid,
+                            new PendingCallback(callbackRecord, displayId, event));
+                } else {
+                    pendingCallback.addDisplayEvent(displayId, event);
+                }
+            }
+        } else {
+            callbackRecord.notifyDisplayEventAsync(displayId, event);
+        }
+    }
+
     private boolean extraLogging(String packageName) {
         return mExtraDisplayEventLogging && mExtraDisplayLoggingPackageName.equals(packageName);
     }
@@ -3571,7 +3583,7 @@
     }
 
     @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
-    private DisplayPowerControllerInterface addDisplayPowerControllerLocked(
+    private DisplayPowerController addDisplayPowerControllerLocked(
             LogicalDisplay display) {
         if (mPowerHandler == null) {
             // initPowerManagement has not yet been called.
@@ -3585,7 +3597,7 @@
         final int userSerial = getUserManager().getUserSerialNumber(mContext.getUserId());
         final BrightnessSetting brightnessSetting = new BrightnessSetting(userSerial,
                 mPersistentDataStore, display, mSyncRoot);
-        final DisplayPowerControllerInterface displayPowerController;
+        final DisplayPowerController displayPowerController;
 
         // If display is internal and has a HighBrightnessModeMetadata mapping, use that.
         // Or create a new one and use that.
@@ -3764,7 +3776,7 @@
 
         public boolean mWifiDisplayScanRequested;
 
-        CallbackRecord(int pid, int uid, IDisplayManagerCallback callback,
+        CallbackRecord(int pid, int uid, @NonNull IDisplayManagerCallback callback,
                 @EventsMask long eventsMask) {
             mPid = pid;
             mUid = uid;
@@ -3792,7 +3804,9 @@
         }
 
         /**
-         * @return {@code false} if RemoteException happens; otherwise {@code true} for success.
+         * @return {@code false} if RemoteException happens; otherwise {@code true} for
+         * success.  This returns true even if the event was deferred because the remote client is
+         * cached.
          */
         public boolean notifyDisplayEventAsync(int displayId, @DisplayEvent int event) {
             if (!shouldSendEvent(event)) {
@@ -3805,9 +3819,19 @@
                             "notifyDisplayEventAsync#notSendingEvent=" + event + ",mEventsMask="
                                     + mEventsMask);
                 }
+                // The client is not interested in this event, so do nothing.
                 return true;
             }
 
+            return transmitDisplayEvent(displayId, event);
+        }
+
+        /**
+         * Transmit a single display event.  The client is presumed ready.  Return true on success
+         * and false if the client died.
+         */
+        private boolean transmitDisplayEvent(int displayId, @DisplayEvent int event) {
+            // The client is ready to receive the event.
             try {
                 mCallback.onDisplayEvent(displayId, event);
                 return true;
@@ -3819,6 +3843,9 @@
             }
         }
 
+        /**
+         * Return true if the client is interested in this event.
+         */
         private boolean shouldSendEvent(@DisplayEvent int event) {
             final long mask = mEventsMask.get();
             switch (event) {
@@ -4373,7 +4400,7 @@
                                     uniqueId, userSerial);
                     if (config == null) {
                         // Get default configuration
-                        DisplayPowerControllerInterface dpc = getDpcFromUniqueIdLocked(uniqueId);
+                        DisplayPowerController dpc = getDpcFromUniqueIdLocked(uniqueId);
                         if (dpc != null) {
                             config = dpc.getDefaultBrightnessConfiguration();
                         }
@@ -4427,7 +4454,7 @@
                     if (display == null || !display.isEnabledLocked()) {
                         return null;
                     }
-                    DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId);
+                    DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
                     if (dpc != null) {
                         return dpc.getBrightnessInfo();
                     }
@@ -4472,7 +4499,7 @@
             final long token = Binder.clearCallingIdentity();
             try {
                 synchronized (mSyncRoot) {
-                    DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId);
+                    DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
                     if (dpc != null) {
                         dpc.setBrightness(brightness);
                     }
@@ -4492,7 +4519,7 @@
             final long token = Binder.clearCallingIdentity();
             try {
                 synchronized (mSyncRoot) {
-                    DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId);
+                    DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
                     if (dpc != null) {
                         brightness = dpc.getScreenBrightnessSetting();
                     }
@@ -4819,7 +4846,7 @@
                             id).getPrimaryDisplayDeviceLocked();
                     final int flags = displayDevice.getDisplayDeviceInfoLocked().flags;
                     if ((flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
-                        final DisplayPowerControllerInterface displayPowerController =
+                        final DisplayPowerController displayPowerController =
                                 mDisplayPowerControllers.get(id);
                         if (displayPowerController != null) {
                             ready &= displayPowerController.requestPowerState(request,
@@ -5200,7 +5227,7 @@
                     return null;
                 }
 
-                DisplayPowerControllerInterface displayPowerController =
+                DisplayPowerController displayPowerController =
                         mDisplayPowerControllers.get(logicalDisplay.getDisplayIdLocked());
                 if (displayPowerController == null) {
                     Slog.w(TAG,
diff --git a/services/core/java/com/android/server/display/DisplayOffloadSessionImpl.java b/services/core/java/com/android/server/display/DisplayOffloadSessionImpl.java
index a188e79..b05a96e 100644
--- a/services/core/java/com/android/server/display/DisplayOffloadSessionImpl.java
+++ b/services/core/java/com/android/server/display/DisplayOffloadSessionImpl.java
@@ -39,12 +39,12 @@
 
     @Nullable
     private final DisplayManagerInternal.DisplayOffloader mDisplayOffloader;
-    private final DisplayPowerControllerInterface mDisplayPowerController;
+    private final DisplayPowerController mDisplayPowerController;
     private boolean mIsActive;
 
     public DisplayOffloadSessionImpl(
             @Nullable DisplayManagerInternal.DisplayOffloader displayOffloader,
-            DisplayPowerControllerInterface displayPowerController) {
+            DisplayPowerController displayPowerController) {
         mDisplayOffloader = displayOffloader;
         mDisplayPowerController = displayPowerController;
     }
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index bf559c1..bb2bed7 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -126,7 +126,7 @@
  * slower by changing the "animator duration scale" option in Development Settings.
  */
 final class DisplayPowerController implements AutomaticBrightnessController.Callbacks,
-        DisplayWhiteBalanceController.Callbacks, DisplayPowerControllerInterface {
+        DisplayWhiteBalanceController.Callbacks{
     private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked";
     private static final String SCREEN_OFF_BLOCKED_TRACE_NAME = "Screen off blocked";
 
@@ -481,7 +481,7 @@
     // DPCs following the brightness of this DPC. This is used in concurrent displays mode - there
     // is one lead display, the additional displays follow the brightness value of the lead display.
     @GuardedBy("mLock")
-    private final SparseArray<DisplayPowerControllerInterface> mDisplayBrightnessFollowers =
+    private final SparseArray<DisplayPowerController> mDisplayBrightnessFollowers =
             new SparseArray();
 
     private boolean mBootCompleted;
@@ -679,7 +679,6 @@
     /**
      * Returns true if the proximity sensor screen-off function is available.
      */
-    @Override
     public boolean isProximitySensorAvailable() {
         return mDisplayPowerProximityStateController.isProximitySensorAvailable();
     }
@@ -691,7 +690,6 @@
      * @param includePackage if false will null out the package name in events
      */
     @Nullable
-    @Override
     public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(
             @UserIdInt int userId, boolean includePackage) {
         if (mBrightnessTracker == null) {
@@ -700,7 +698,6 @@
         return mBrightnessTracker.getEvents(userId, includePackage);
     }
 
-    @Override
     public void onSwitchUser(@UserIdInt int newUserId, int userSerial, float newBrightness) {
         Message msg = mHandler.obtainMessage(MSG_SWITCH_USER, newUserId, userSerial, newBrightness);
         mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
@@ -737,7 +734,6 @@
     }
 
     @Nullable
-    @Override
     public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats(
             @UserIdInt int userId) {
         if (mBrightnessTracker == null) {
@@ -749,7 +745,6 @@
     /**
      * Persist the brightness slider events and ambient brightness stats to disk.
      */
-    @Override
     public void persistBrightnessTrackerState() {
         if (mBrightnessTracker != null) {
             mBrightnessTracker.persistBrightnessTrackerState();
@@ -806,7 +801,6 @@
         }
     }
 
-    @Override
     public void overrideDozeScreenState(int displayState, @Display.StateReason int reason) {
         Slog.i(TAG, "New offload doze override: " + Display.stateToString(displayState));
         if (mDisplayOffloadSession != null
@@ -833,7 +827,6 @@
         }
     }
 
-    @Override
     public void setDisplayOffloadSession(DisplayOffloadSession session) {
         if (session == mDisplayOffloadSession) {
             return;
@@ -842,7 +835,6 @@
         mDisplayOffloadSession = session;
     }
 
-    @Override
     public BrightnessConfiguration getDefaultBrightnessConfiguration() {
         if (mAutomaticBrightnessController == null) {
             return null;
@@ -857,7 +849,6 @@
      *
      * Make sure DisplayManagerService.mSyncRoot lock is held when this is called
      */
-    @Override
     public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata, int leadDisplayId) {
         mLeadDisplayId = leadDisplayId;
         final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
@@ -939,7 +930,6 @@
      * This method should be called when the DisplayPowerController is no longer in use; i.e. when
      * the {@link #mDisplayId display} has been removed.
      */
-    @Override
     public void stop() {
         synchronized (mLock) {
             clearDisplayBrightnessFollowersLocked();
@@ -1216,7 +1206,6 @@
         }
     }
 
-    @Override
     public void setAutomaticScreenBrightnessMode(
             @AutomaticBrightnessController.AutomaticBrightnessMode int mode) {
         Message msg = mHandler.obtainMessage();
@@ -1314,7 +1303,7 @@
         boolean mustInitialize = false;
         mBrightnessReasonTemp.set(null);
         mTempBrightnessEvent.reset();
-        SparseArray<DisplayPowerControllerInterface> displayBrightnessFollowers;
+        SparseArray<DisplayPowerController> displayBrightnessFollowers;
         synchronized (mLock) {
             if (mStopped) {
                 return;
@@ -1547,7 +1536,7 @@
         float ambientLux = mAutomaticBrightnessController == null ? 0
                 : mAutomaticBrightnessController.getAmbientLux();
         for (int i = 0; i < displayBrightnessFollowers.size(); i++) {
-            DisplayPowerControllerInterface follower = displayBrightnessFollowers.valueAt(i);
+            DisplayPowerController follower = displayBrightnessFollowers.valueAt(i);
             follower.setBrightnessToFollow(rawBrightnessState,
                     mDisplayBrightnessController.convertToNits(rawBrightnessState),
                     ambientLux, slowChange);
@@ -1904,7 +1893,6 @@
         }
     }
 
-    @Override
     public void updateBrightness() {
         sendUpdatePowerState();
     }
@@ -1913,12 +1901,10 @@
      * Ignores the proximity sensor until the sensor state changes, but only if the sensor is
      * currently enabled and forcing the screen to be dark.
      */
-    @Override
     public void ignoreProximitySensorUntilChanged() {
         mDisplayPowerProximityStateController.ignoreProximitySensorUntilChanged();
     }
 
-    @Override
     public void setBrightnessConfiguration(BrightnessConfiguration c,
             boolean shouldResetShortTermModel) {
         Message msg = mHandler.obtainMessage(MSG_CONFIGURE_BRIGHTNESS,
@@ -1926,28 +1912,24 @@
         msg.sendToTarget();
     }
 
-    @Override
     public void setTemporaryBrightness(float brightness) {
         Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_BRIGHTNESS,
                 Float.floatToIntBits(brightness), 0 /*unused*/);
         msg.sendToTarget();
     }
 
-    @Override
     public void setTemporaryAutoBrightnessAdjustment(float adjustment) {
         Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT,
                 Float.floatToIntBits(adjustment), 0 /*unused*/);
         msg.sendToTarget();
     }
 
-    @Override
     public void setBrightnessFromOffload(float brightness) {
         Message msg = mHandler.obtainMessage(MSG_SET_BRIGHTNESS_FROM_OFFLOAD,
                 Float.floatToIntBits(brightness), 0 /*unused*/);
         mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
     }
 
-    @Override
     public float[] getAutoBrightnessLevels(
             @AutomaticBrightnessController.AutomaticBrightnessMode int mode) {
         int preset = Settings.System.getIntForUser(mContext.getContentResolver(),
@@ -1956,7 +1938,6 @@
         return mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels(mode, preset);
     }
 
-    @Override
     public float[] getAutoBrightnessLuxLevels(
             @AutomaticBrightnessController.AutomaticBrightnessMode int mode) {
         int preset = Settings.System.getIntForUser(mContext.getContentResolver(),
@@ -1965,7 +1946,6 @@
         return mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(mode, preset);
     }
 
-    @Override
     public BrightnessInfo getBrightnessInfo() {
         synchronized (mCachedBrightnessInfo) {
             return new BrightnessInfo(
@@ -1979,7 +1959,6 @@
         }
     }
 
-    @Override
     public void onBootCompleted() {
         Message msg = mHandler.obtainMessage(MSG_BOOT_COMPLETED);
         mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
@@ -2495,18 +2474,14 @@
         }
     }
 
-
-    @Override
     public float getScreenBrightnessSetting() {
         return mDisplayBrightnessController.getScreenBrightnessSetting();
     }
 
-    @Override
     public float getDozeBrightnessForOffload() {
         return mDisplayBrightnessController.getCurrentBrightness() * mDozeScaleFactor;
     }
 
-    @Override
     public void setBrightness(float brightness) {
         // After HBMController and NBMController migration to Clampers framework
         // currentBrightnessMax should be taken from clampers controller
@@ -2515,7 +2490,6 @@
                 mBrightnessRangeController.getCurrentBrightnessMax());
     }
 
-    @Override
     public void setBrightness(float brightness, int userSerial) {
         // After HBMController and NBMController migration to Clampers framework
         // currentBrightnessMax should be taken from clampers controller
@@ -2524,17 +2498,14 @@
                 mBrightnessRangeController.getCurrentBrightnessMax());
     }
 
-    @Override
     public int getDisplayId() {
         return mDisplayId;
     }
 
-    @Override
     public int getLeadDisplayId() {
         return mLeadDisplayId;
     }
 
-    @Override
     public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux,
             boolean slowChange) {
         mBrightnessRangeController.onAmbientLuxChange(ambientLux);
@@ -2595,16 +2566,14 @@
                 mAutomaticBrightnessController.getLastSensorTimestamps());
     }
 
-    @Override
-    public void addDisplayBrightnessFollower(DisplayPowerControllerInterface follower) {
+    public void addDisplayBrightnessFollower(DisplayPowerController follower) {
         synchronized (mLock) {
             mDisplayBrightnessFollowers.append(follower.getDisplayId(), follower);
             sendUpdatePowerStateLocked();
         }
     }
 
-    @Override
-    public void removeDisplayBrightnessFollower(DisplayPowerControllerInterface follower) {
+    public void removeDisplayBrightnessFollower(DisplayPowerController follower) {
         synchronized (mLock) {
             mDisplayBrightnessFollowers.remove(follower.getDisplayId());
             mHandler.postAtTime(() -> follower.setBrightnessToFollow(
@@ -2616,7 +2585,7 @@
     @GuardedBy("mLock")
     private void clearDisplayBrightnessFollowersLocked() {
         for (int i = 0; i < mDisplayBrightnessFollowers.size(); i++) {
-            DisplayPowerControllerInterface follower = mDisplayBrightnessFollowers.valueAt(i);
+            DisplayPowerController follower = mDisplayBrightnessFollowers.valueAt(i);
             mHandler.postAtTime(() -> follower.setBrightnessToFollow(
                     PowerManager.BRIGHTNESS_INVALID_FLOAT, BrightnessMappingStrategy.INVALID_NITS,
                     /* ambientLux= */ 0, /* slowChange= */ false), mClock.uptimeMillis());
@@ -2624,7 +2593,6 @@
         mDisplayBrightnessFollowers.clear();
     }
 
-    @Override
     public void dump(final PrintWriter pw) {
         synchronized (mLock) {
             pw.println();
@@ -3161,19 +3129,17 @@
         }
     }
 
-    @Override
     public void setAutoBrightnessLoggingEnabled(boolean enabled) {
         if (mAutomaticBrightnessController != null) {
             mAutomaticBrightnessController.setLoggingEnabled(enabled);
         }
     }
 
-    @Override // DisplayWhiteBalanceController.Callbacks
+    // DisplayWhiteBalanceController.Callbacks
     public void updateWhiteBalance() {
         sendUpdatePowerState();
     }
 
-    @Override
     public void setDisplayWhiteBalanceLoggingEnabled(boolean enabled) {
         Message msg = mHandler.obtainMessage();
         msg.what = MSG_SET_DWBC_LOGGING_ENABLED;
@@ -3181,7 +3147,6 @@
         msg.sendToTarget();
     }
 
-    @Override
     public void setAmbientColorTemperatureOverride(float cct) {
         Message msg = mHandler.obtainMessage();
         msg.what = MSG_SET_DWBC_COLOR_OVERRIDE;
diff --git a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
deleted file mode 100644
index d28578a..0000000
--- a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.display;
-
-import android.content.pm.ParceledListSlice;
-import android.hardware.display.AmbientBrightnessDayStats;
-import android.hardware.display.BrightnessChangeEvent;
-import android.hardware.display.BrightnessConfiguration;
-import android.hardware.display.BrightnessInfo;
-import android.hardware.display.DisplayManagerInternal;
-import android.os.PowerManager;
-import android.view.Display;
-
-import java.io.PrintWriter;
-
-/**
- * An interface to manage the display's power state and brightness
- */
-public interface DisplayPowerControllerInterface {
-    /**
-     * Notified when the display is changed.
-     *
-     * We use this to apply any changes that might be needed when displays get swapped on foldable
-     * devices, when layouts change, etc.
-     *
-     * Must be called while holding the SyncRoot lock.
-     *
-     * @param hbmInfo The high brightness mode metadata, like
-     *                remaining time and hbm events, for the corresponding
-     *                physical display, to make sure we stay within the safety margins.
-     * @param leadDisplayId The display who is considered our "leader" for things like brightness.
-     */
-    void onDisplayChanged(HighBrightnessModeMetadata hbmInfo, int leadDisplayId);
-
-    /**
-     * Unregisters all listeners and interrupts all running threads; halting future work.
-     *
-     * This method should be called when the DisplayPowerController is no longer in use; i.e. when
-     * the display has been removed.
-     */
-    void stop();
-
-    /**
-     * Used to update the display's BrightnessConfiguration
-     * @param config The new BrightnessConfiguration
-     */
-    void setBrightnessConfiguration(BrightnessConfiguration config,
-            boolean shouldResetShortTermModel);
-
-    /**
-     * Used to set the ambient color temperature of the Display
-     * @param ambientColorTemperature The target ambientColorTemperature
-     */
-    void setAmbientColorTemperatureOverride(float ambientColorTemperature);
-
-    /**
-     * Used to decide the associated AutomaticBrightnessController's BrightnessMode
-     * @param mode The auto-brightness mode
-     */
-    void setAutomaticScreenBrightnessMode(
-            @AutomaticBrightnessController.AutomaticBrightnessMode int mode);
-
-    /**
-     * Used to enable/disable the logging of the WhileBalance associated entities
-     * @param enabled Flag which represents if the logging is the be enabled
-     */
-    void setDisplayWhiteBalanceLoggingEnabled(boolean enabled);
-
-    /**
-     * Used to dump the state.
-     * @param writer The PrintWriter used to dump the state.
-     */
-    void dump(PrintWriter writer);
-
-    /**
-     * Used to get the ambient brightness stats
-     */
-    ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats(int userId);
-
-    /**
-     * Get the default brightness configuration
-     */
-    BrightnessConfiguration getDefaultBrightnessConfiguration();
-
-    /**
-     * Set the screen brightness of the associated display
-     * @param brightness The value to which the brightness is to be set
-     */
-    void setBrightness(float brightness);
-
-    /**
-     * Set the screen brightness of the associated display
-     * @param brightness The value to which the brightness is to be set
-     * @param userSerial The user for which the brightness value is to be set.
-     */
-    void setBrightness(float brightness, int userSerial);
-
-    /**
-     * Checks if the proximity sensor is available
-     */
-    boolean isProximitySensorAvailable();
-
-    /**
-     * Persist the brightness slider events and ambient brightness stats to disk.
-     */
-    void persistBrightnessTrackerState();
-
-    /**
-     * Ignores the proximity sensor until the sensor state changes, but only if the sensor is
-     * currently enabled and forcing the screen to be dark.
-     */
-    void ignoreProximitySensorUntilChanged();
-
-    /**
-     * Requests a new power state.
-     *
-     * @param request The requested power state.
-     * @param waitForNegativeProximity If true, issues a request to wait for
-     * negative proximity before turning the screen back on,
-     * assuming the screen was turned off by the proximity sensor.
-     * @return True if display is ready, false if there are important changes that must
-     * be made asynchronously.
-     */
-    boolean requestPowerState(DisplayManagerInternal.DisplayPowerRequest request,
-            boolean waitForNegativeProximity);
-
-    /**
-     * Overrides the current doze screen state.
-     *
-     * @param displayState the new doze display state.
-     * @param reason the reason behind the new doze display state.
-     */
-    void overrideDozeScreenState(int displayState, @Display.StateReason int reason);
-
-    void setDisplayOffloadSession(DisplayManagerInternal.DisplayOffloadSession session);
-
-    /**
-     * Sets up the temporary autobrightness adjustment when the user is yet to settle down to a
-     * value.
-     */
-    void setTemporaryAutoBrightnessAdjustment(float adjustment);
-
-    /**
-     * Sets temporary brightness from the offload chip until we get a brightness value from
-     * the light sensor.
-     * @param brightness The brightness value between {@link PowerManager.BRIGHTNESS_MIN} and
-     * {@link PowerManager.BRIGHTNESS_MAX}. Values outside of that range will be ignored.
-     */
-    void setBrightnessFromOffload(float brightness);
-
-    /**
-     * Gets the screen brightness setting
-     */
-    float getScreenBrightnessSetting();
-
-    /**
-     * Gets the brightness value used when the device is in doze
-     */
-    float getDozeBrightnessForOffload();
-
-    /**
-     * Sets up the temporary brightness for the associated display
-     */
-    void setTemporaryBrightness(float brightness);
-
-    /**
-     * Gets the associated {@link BrightnessInfo}
-     */
-    BrightnessInfo getBrightnessInfo();
-
-    /**
-     * Get the {@link BrightnessChangeEvent}s for the specified user.
-     */
-    ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(int userId, boolean hasUsageStats);
-
-    /**
-     * Sets up the logging for the associated {@link AutomaticBrightnessController}
-     * @param enabled Flag to represent if the logging is to be enabled
-     */
-    void setAutoBrightnessLoggingEnabled(boolean enabled);
-
-    /**
-     * Handles the changes to be done to update the brightness when the user is changed
-     * @param newUserId The new userId
-     * @param userSerial The serial number of the new user
-     * @param newBrightness The brightness for the new user
-     */
-    void onSwitchUser(int newUserId, int userSerial, float newBrightness);
-
-    /**
-     * Get the ID of the display associated with this DPC.
-     * @return The display ID
-     */
-    int getDisplayId();
-
-    /**
-     * Get the ID of the display that is the leader of this DPC.
-     *
-     * Note that this is different than the display associated with the DPC. The leader is another
-     * display which we follow for things like brightness.
-     *
-     * Must be called while holding the SyncRoot lock.
-     */
-    int getLeadDisplayId();
-
-    /**
-     * Set the brightness to follow if this is an additional display in a set of concurrent
-     * displays.
-     * @param leadDisplayBrightness The brightness of the lead display in the set of concurrent
-     *                              displays
-     * @param nits The brightness value in nits if the device supports nits. Set to a negative
-     *             number otherwise.
-     * @param ambientLux The lux value that will be passed to {@link HighBrightnessModeController}
-     * @param slowChange Indicates whether we should slowly animate to the given brightness value.
-     */
-    void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux,
-            boolean slowChange);
-
-    /**
-     * Add an additional display that will copy the brightness value from this display. This is used
-     * when the device is in concurrent displays mode.
-     * @param follower The DPC that should copy the brightness value from this DPC
-     */
-    void addDisplayBrightnessFollower(DisplayPowerControllerInterface follower);
-
-    /**
-     * Removes the given display from the list of brightness followers.
-     * @param follower The DPC to remove from the followers list
-     */
-    void removeDisplayBrightnessFollower(DisplayPowerControllerInterface follower);
-
-    /**
-     * Indicate that boot has been completed and the screen is ready to update.
-     */
-    void onBootCompleted();
-
-    /**
-     * Get the brightness levels used to determine automatic brightness based on lux levels.
-     * @param mode The auto-brightness mode
-     * @return The brightness levels for the specified mode. The values are between
-     * {@link PowerManager.BRIGHTNESS_MIN} and {@link PowerManager.BRIGHTNESS_MAX}.
-     */
-    float[] getAutoBrightnessLevels(
-            @AutomaticBrightnessController.AutomaticBrightnessMode int mode);
-
-    /**
-     * Get the lux levels used to determine automatic brightness.
-     * @param mode The auto-brightness mode
-     * @return The lux levels for the specified mode
-     */
-    float[] getAutoBrightnessLuxLevels(
-            @AutomaticBrightnessController.AutomaticBrightnessMode int mode);
-}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 1220542..52bf537 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -597,9 +597,6 @@
         mKeyRemapper.systemRunning();
         mPointerIconCache.systemRunning();
         mKeyboardGlyphManager.systemRunning();
-        if (mTouchpadDebugViewController != null) {
-            mTouchpadDebugViewController.systemRunning();
-        }
     }
 
     private void reloadDeviceAliases() {
@@ -3340,6 +3337,13 @@
         }
     }
 
+    void updateTouchpadVisualizerEnabled(boolean enabled) {
+        mNative.setShouldNotifyTouchpadHardwareState(enabled);
+        if (mTouchpadDebugViewController != null) {
+            mTouchpadDebugViewController.updateTouchpadVisualizerEnabled(enabled);
+        }
+    }
+
     void updatePointerLocationEnabled(boolean enabled) {
         mWindowManagerCallbacks.notifyPointerLocationChanged(enabled);
     }
diff --git a/services/core/java/com/android/server/input/InputSettingsObserver.java b/services/core/java/com/android/server/input/InputSettingsObserver.java
index ef61d02..835fb72 100644
--- a/services/core/java/com/android/server/input/InputSettingsObserver.java
+++ b/services/core/java/com/android/server/input/InputSettingsObserver.java
@@ -180,7 +180,7 @@
     }
 
     private void updateTouchpadHardwareStateNotificationsEnabled() {
-        mNative.setShouldNotifyTouchpadHardwareState(InputSettings.useTouchpadVisualizer(mContext));
+        mService.updateTouchpadVisualizerEnabled(InputSettings.useTouchpadVisualizer(mContext));
     }
 
     private void updateTouchpadRightClickZoneEnabled() {
diff --git a/services/core/java/com/android/server/input/debug/TouchpadDebugView.java b/services/core/java/com/android/server/input/debug/TouchpadDebugView.java
index 5fca771..7785ffb 100644
--- a/services/core/java/com/android/server/input/debug/TouchpadDebugView.java
+++ b/services/core/java/com/android/server/input/debug/TouchpadDebugView.java
@@ -16,23 +16,69 @@
 
 package com.android.server.input.debug;
 
+import android.annotation.NonNull;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.util.Slog;
 import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+import android.view.WindowManager;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-public class TouchpadDebugView extends LinearLayout {
+import java.util.Objects;
 
+public class TouchpadDebugView extends LinearLayout {
     /**
      * Input device ID for the touchpad that this debug view is displaying.
      */
     private final int mTouchpadId;
 
+    @NonNull
+    private final WindowManager mWindowManager;
+
+    @NonNull
+    private final WindowManager.LayoutParams mWindowLayoutParams;
+
+    private final int mTouchSlop;
+
+    private float mTouchDownX;
+    private float mTouchDownY;
+    private int mScreenWidth;
+    private int mScreenHeight;
+    private int mWindowLocationBeforeDragX;
+    private int mWindowLocationBeforeDragY;
+
     public TouchpadDebugView(Context context, int touchpadId) {
         super(context);
         mTouchpadId = touchpadId;
+        mWindowManager =
+                Objects.requireNonNull(getContext().getSystemService(WindowManager.class));
         init(context);
+        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+
+        // TODO(b/360137366): Use the hardware properties to initialise layout parameters.
+        mWindowLayoutParams = new WindowManager.LayoutParams();
+        mWindowLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+        mWindowLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+        mWindowLayoutParams.privateFlags |=
+                WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
+        mWindowLayoutParams.setFitInsetsTypes(0);
+        mWindowLayoutParams.layoutInDisplayCutoutMode =
+                WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+        mWindowLayoutParams.format = PixelFormat.TRANSLUCENT;
+        mWindowLayoutParams.setTitle("TouchpadDebugView - display " + mContext.getDisplayId());
+
+        mWindowLayoutParams.x = 40;
+        mWindowLayoutParams.y = 100;
+        mWindowLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
+        mWindowLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
+        mWindowLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
     }
 
     private void init(Context context) {
@@ -43,14 +89,12 @@
         setBackgroundColor(Color.TRANSPARENT);
 
         // TODO(b/286551975): Replace this content with the touchpad debug view.
-
         TextView textView1 = new TextView(context);
         textView1.setBackgroundColor(Color.parseColor("#FFFF0000"));
         textView1.setTextSize(20);
         textView1.setText("Touchpad Debug View 1");
         textView1.setGravity(Gravity.CENTER);
         textView1.setTextColor(Color.WHITE);
-
         textView1.setLayoutParams(new LayoutParams(1000, 200));
 
         TextView textView2 = new TextView(context);
@@ -63,9 +107,98 @@
 
         addView(textView1);
         addView(textView2);
+
+        updateScreenDimensions();
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        float deltaX;
+        float deltaY;
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                mWindowLocationBeforeDragX = mWindowLayoutParams.x;
+                mWindowLocationBeforeDragY = mWindowLayoutParams.y;
+                mTouchDownX = event.getRawX() - mWindowLocationBeforeDragX;
+                mTouchDownY = event.getRawY() - mWindowLocationBeforeDragY;
+                return true;
+
+            case MotionEvent.ACTION_MOVE:
+                deltaX = event.getRawX() - mWindowLayoutParams.x - mTouchDownX;
+                deltaY = event.getRawY() - mWindowLayoutParams.y - mTouchDownY;
+                Slog.d("TouchpadDebugView", "Slop = " + mTouchSlop);
+                if (isSlopExceeded(deltaX, deltaY)) {
+                    Slog.d("TouchpadDebugView", "Slop exceeded");
+                    mWindowLayoutParams.x =
+                            Math.max(0, Math.min((int) (event.getRawX() - mTouchDownX),
+                                    mScreenWidth - this.getWidth()));
+                    mWindowLayoutParams.y =
+                            Math.max(0, Math.min((int) (event.getRawY() - mTouchDownY),
+                                    mScreenHeight - this.getHeight()));
+
+                    Slog.d("TouchpadDebugView", "New position X: "
+                            + mWindowLayoutParams.x + ", Y: " + mWindowLayoutParams.y);
+
+                    mWindowManager.updateViewLayout(this, mWindowLayoutParams);
+                }
+                return true;
+
+            case MotionEvent.ACTION_UP:
+                deltaX = event.getRawX() - mWindowLayoutParams.x - mTouchDownX;
+                deltaY = event.getRawY() - mWindowLayoutParams.y - mTouchDownY;
+                if (!isSlopExceeded(deltaX, deltaY)) {
+                    performClick();
+                }
+                return true;
+
+            case MotionEvent.ACTION_CANCEL:
+                // Move the window back to the original position
+                mWindowLayoutParams.x = mWindowLocationBeforeDragX;
+                mWindowLayoutParams.y = mWindowLocationBeforeDragY;
+                mWindowManager.updateViewLayout(this, mWindowLayoutParams);
+                return true;
+
+            default:
+                return super.onTouchEvent(event);
+        }
+    }
+
+    @Override
+    public boolean performClick() {
+        super.performClick();
+        Slog.d("TouchpadDebugView", "You clicked me!");
+        return true;
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        updateScreenDimensions();
+
+        // Adjust view position to stay within screen bounds after rotation
+        mWindowLayoutParams.x =
+                Math.max(0, Math.min(mWindowLayoutParams.x, mScreenWidth - getWidth()));
+        mWindowLayoutParams.y =
+                Math.max(0, Math.min(mWindowLayoutParams.y, mScreenHeight - getHeight()));
+        mWindowManager.updateViewLayout(this, mWindowLayoutParams);
+    }
+
+    private boolean isSlopExceeded(float deltaX, float deltaY) {
+        return deltaX * deltaX + deltaY * deltaY >= mTouchSlop * mTouchSlop;
+    }
+
+    private void updateScreenDimensions() {
+        Rect windowBounds =
+                mWindowManager.getCurrentWindowMetrics().getBounds();
+        mScreenWidth = windowBounds.width();
+        mScreenHeight = windowBounds.height();
     }
 
     public int getTouchpadId() {
         return mTouchpadId;
     }
+
+    public WindowManager.LayoutParams getWindowLayoutParams() {
+        return mWindowLayoutParams;
+    }
 }
diff --git a/services/core/java/com/android/server/input/debug/TouchpadDebugViewController.java b/services/core/java/com/android/server/input/debug/TouchpadDebugViewController.java
index c7760c6..c28e74a 100644
--- a/services/core/java/com/android/server/input/debug/TouchpadDebugViewController.java
+++ b/services/core/java/com/android/server/input/debug/TouchpadDebugViewController.java
@@ -18,14 +18,10 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
-import android.graphics.PixelFormat;
-import android.hardware.display.DisplayManager;
 import android.hardware.input.InputManager;
 import android.os.Handler;
 import android.os.Looper;
 import android.util.Slog;
-import android.view.Display;
-import android.view.Gravity;
 import android.view.InputDevice;
 import android.view.WindowManager;
 
@@ -34,58 +30,72 @@
 
 import java.util.Objects;
 
-public class TouchpadDebugViewController {
+public class TouchpadDebugViewController implements InputManager.InputDeviceListener {
 
-    private static final String TAG = "TouchpadDebugViewController";
+    private static final String TAG = "TouchpadDebugView";
 
     private final Context mContext;
     private final Handler mHandler;
+
     @Nullable
     private TouchpadDebugView mTouchpadDebugView;
+
     private final InputManagerService mInputManagerService;
+    private boolean mTouchpadVisualizerEnabled = false;
 
     public TouchpadDebugViewController(Context context, Looper looper,
-                                       InputManagerService inputManagerService) {
-        final DisplayManager displayManager = Objects.requireNonNull(
-                context.getSystemService(DisplayManager.class));
-        final Display defaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
-        mContext = context.createDisplayContext(defaultDisplay);
+            InputManagerService inputManagerService) {
+        //TODO(b/363979581): Handle multi-display scenarios
+        mContext = context;
         mHandler = new Handler(looper);
         mInputManagerService = inputManagerService;
     }
 
-    public void systemRunning() {
+    @Override
+    public void onInputDeviceAdded(int deviceId) {
         final InputManager inputManager = Objects.requireNonNull(
                 mContext.getSystemService(InputManager.class));
-        inputManager.registerInputDeviceListener(mInputDeviceListener, mHandler);
-        for (int deviceId : inputManager.getInputDeviceIds()) {
-            mInputDeviceListener.onInputDeviceAdded(deviceId);
+        InputDevice inputDevice = inputManager.getInputDevice(deviceId);
+
+        if (Objects.requireNonNull(inputDevice).supportsSource(
+                InputDevice.SOURCE_TOUCHPAD | InputDevice.SOURCE_MOUSE)
+                && mTouchpadVisualizerEnabled) {
+            showDebugView(deviceId);
         }
     }
 
-    private final InputManager.InputDeviceListener mInputDeviceListener =
-            new InputManager.InputDeviceListener() {
-                @Override
-                public void onInputDeviceAdded(int deviceId) {
-                    final InputManager inputManager = Objects.requireNonNull(
-                            mContext.getSystemService(InputManager.class));
-                    InputDevice inputDevice = inputManager.getInputDevice(deviceId);
+    @Override
+    public void onInputDeviceRemoved(int deviceId) {
+        hideDebugView(deviceId);
+    }
 
-                    if (Objects.requireNonNull(inputDevice).supportsSource(
-                            InputDevice.SOURCE_TOUCHPAD | InputDevice.SOURCE_MOUSE)) {
-                        showDebugView(deviceId);
-                    }
-                }
+    @Override
+    public void onInputDeviceChanged(int deviceId) {
+    }
 
-                @Override
-                public void onInputDeviceRemoved(int deviceId) {
-                    hideDebugView(deviceId);
-                }
-
-                @Override
-                public void onInputDeviceChanged(int deviceId) {
-                }
-            };
+    /**
+     * Notify the controller that the touchpad visualizer setting value has changed.
+     * This must be called from the same looper thread as {@code mHandler}.
+     */
+    public void updateTouchpadVisualizerEnabled(boolean touchpadVisualizerEnabled) {
+        if (mTouchpadVisualizerEnabled == touchpadVisualizerEnabled) {
+            return;
+        }
+        mTouchpadVisualizerEnabled = touchpadVisualizerEnabled;
+        final InputManager inputManager = Objects.requireNonNull(
+                mContext.getSystemService(InputManager.class));
+        if (touchpadVisualizerEnabled) {
+            inputManager.registerInputDeviceListener(this, mHandler);
+            for (int deviceId : inputManager.getInputDeviceIds()) {
+                onInputDeviceAdded(deviceId);
+            }
+        } else {
+            if (mTouchpadDebugView != null) {
+                hideDebugView(mTouchpadDebugView.getTouchpadId());
+            }
+            inputManager.unregisterInputDeviceListener(this);
+        }
+    }
 
     private void showDebugView(int touchpadId) {
         if (mTouchpadDebugView != null) {
@@ -95,32 +105,15 @@
                 mContext.getSystemService(WindowManager.class));
 
         mTouchpadDebugView = new TouchpadDebugView(mContext, touchpadId);
+        final WindowManager.LayoutParams mWindowLayoutParams =
+                mTouchpadDebugView.getWindowLayoutParams();
 
-        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
-        lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
-        lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
-        lp.setFitInsetsTypes(0);
-        lp.layoutInDisplayCutoutMode =
-                WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-        lp.format = PixelFormat.TRANSLUCENT;
-        lp.setTitle("TouchpadDebugView - display " + mContext.getDisplayId());
-        lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
-
-        lp.x = 40;
-        lp.y = 100;
-        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
-        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
-        lp.gravity = Gravity.TOP | Gravity.LEFT;
-
-        wm.addView(mTouchpadDebugView, lp);
+        wm.addView(mTouchpadDebugView, mWindowLayoutParams);
         Slog.d(TAG, "Touchpad debug view created.");
 
         TouchpadHardwareProperties mTouchpadHardwareProperties =
                 mInputManagerService.getTouchpadHardwareProperties(
                         touchpadId);
-        // TODO(b/360137366): Use the hardware properties to initialise layout parameters.
         if (mTouchpadHardwareProperties != null) {
             Slog.d(TAG, mTouchpadHardwareProperties.toString());
         } else {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 7cfd2cc..af0ccf9 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -350,13 +350,15 @@
     @BinderThread
     private int resolveImeUserIdLocked(@UserIdInt int callingProcessUserId,
             @NonNull IInputMethodClient client) {
-        if (mConcurrentMultiUserModeEnabled
-                && callingProcessUserId == UserHandle.USER_SYSTEM) {
-            final var clientState = mClientController.getClient(client.asBinder());
-            return mUserManagerInternal.getUserAssignedToDisplay(
-                    clientState.mSelfReportedDisplayId);
+        if (mConcurrentMultiUserModeEnabled) {
+            if (callingProcessUserId == UserHandle.USER_SYSTEM) {
+                final var clientState = mClientController.getClient(client.asBinder());
+                return mUserManagerInternal.getUserAssignedToDisplay(
+                        clientState.mSelfReportedDisplayId);
+            }
+            return callingProcessUserId;
         }
-        return callingProcessUserId;
+        return mCurrentImeUserId;
     }
 
    /**
diff --git a/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java b/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java
index c8cb54f..bad959a 100644
--- a/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java
+++ b/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java
@@ -19,6 +19,9 @@
 import static android.app.UiModeManager.MODE_ATTENTION_THEME_OVERLAY_NIGHT;
 import static android.app.UiModeManager.MODE_ATTENTION_THEME_OVERLAY_OFF;
 
+import static com.android.server.notification.ZenLog.traceApplyDeviceEffect;
+import static com.android.server.notification.ZenLog.traceScheduleApplyDeviceEffect;
+
 import android.app.UiModeManager;
 import android.app.WallpaperManager;
 import android.content.BroadcastReceiver;
@@ -77,6 +80,8 @@
             if (mLastAppliedEffects.shouldSuppressAmbientDisplay()
                     != effects.shouldSuppressAmbientDisplay()) {
                 try {
+                    traceApplyDeviceEffect("suppressAmbientDisplay",
+                            effects.shouldSuppressAmbientDisplay());
                     mPowerManager.suppressAmbientDisplay(SUPPRESS_AMBIENT_DISPLAY_TOKEN,
                             effects.shouldSuppressAmbientDisplay());
                 } catch (Exception e) {
@@ -87,6 +92,8 @@
             if (mLastAppliedEffects.shouldDisplayGrayscale() != effects.shouldDisplayGrayscale()) {
                 if (mColorDisplayManager != null) {
                     try {
+                        traceApplyDeviceEffect("displayGrayscale",
+                                effects.shouldDisplayGrayscale());
                         mColorDisplayManager.setSaturationLevel(
                                 effects.shouldDisplayGrayscale() ? SATURATION_LEVEL_GRAYSCALE
                                         : SATURATION_LEVEL_FULL_COLOR);
@@ -99,6 +106,7 @@
             if (mLastAppliedEffects.shouldDimWallpaper() != effects.shouldDimWallpaper()) {
                 if (mWallpaperManager != null) {
                     try {
+                        traceApplyDeviceEffect("dimWallpaper", effects.shouldDimWallpaper());
                         mWallpaperManager.setWallpaperDimAmount(
                                 effects.shouldDimWallpaper() ? WALLPAPER_DIM_AMOUNT_DIMMED
                                         : WALLPAPER_DIM_AMOUNT_NORMAL);
@@ -134,6 +142,7 @@
             unregisterScreenOffReceiver();
             updateNightModeImmediately(useNightMode);
         } else {
+            traceScheduleApplyDeviceEffect("nightMode", useNightMode);
             registerScreenOffReceiver();
         }
     }
@@ -150,6 +159,7 @@
     private void updateNightModeImmediately(boolean useNightMode) {
         Binder.withCleanCallingIdentity(() -> {
             try {
+                traceApplyDeviceEffect("nightMode", useNightMode);
                 mUiModeManager.setAttentionModeThemeOverlay(
                         useNightMode ? MODE_ATTENTION_THEME_OVERLAY_NIGHT
                                 : MODE_ATTENTION_THEME_OVERLAY_OFF);
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 1fdb57c..48b60b2 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -75,7 +75,9 @@
 import com.android.internal.util.function.TriPredicate;
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
+import com.android.server.LocalServices;
 import com.android.server.notification.NotificationManagerService.DumpFilter;
+import com.android.server.pm.UserManagerInternal;
 import com.android.server.utils.TimingsTraceAndSlog;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -134,6 +136,7 @@
     private final UserProfiles mUserProfiles;
     protected final IPackageManager mPm;
     protected final UserManager mUm;
+    private final UserManagerInternal mUserManagerInternal;
     private final Config mConfig;
     private final Handler mHandler = new Handler(Looper.getMainLooper());
 
@@ -195,6 +198,7 @@
         mConfig = getConfig();
         mApprovalLevel = APPROVAL_BY_COMPONENT;
         mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
     }
 
     abstract protected Config getConfig();
@@ -1372,9 +1376,14 @@
     @GuardedBy("mMutex")
     protected void populateComponentsToBind(SparseArray<Set<ComponentName>> componentsToBind,
             final IntArray activeUsers,
-            SparseArray<ArraySet<ComponentName>> approvedComponentsByUser) {
-        mEnabledServicesForCurrentProfiles.clear();
-        mEnabledServicesPackageNames.clear();
+            SparseArray<ArraySet<ComponentName>> approvedComponentsByUser,
+            boolean isVisibleBackgroundUser) {
+        // When it is a visible background user in Automotive MUMD environment,
+        // don't clear mEnabledServicesForCurrentProfile and mEnabledServicesPackageNames.
+        if (!isVisibleBackgroundUser) {
+            mEnabledServicesForCurrentProfiles.clear();
+            mEnabledServicesPackageNames.clear();
+        }
         final int nUserIds = activeUsers.size();
 
         for (int i = 0; i < nUserIds; ++i) {
@@ -1395,7 +1404,12 @@
             }
 
             componentsToBind.put(userId, add);
-
+            // When it is a visible background user in Automotive MUMD environment,
+            // skip adding items to mEnabledServicesForCurrentProfile
+            // and mEnabledServicesPackageNames.
+            if (isVisibleBackgroundUser) {
+                continue;
+            }
             mEnabledServicesForCurrentProfiles.addAll(userComponents);
 
             for (int j = 0; j < userComponents.size(); j++) {
@@ -1443,7 +1457,10 @@
         IntArray userIds = mUserProfiles.getCurrentProfileIds();
         boolean rebindAllCurrentUsers = mUserProfiles.isProfileUser(userToRebind, mContext)
                 && allowRebindForParentUser();
+        boolean isVisibleBackgroundUser = false;
         if (userToRebind != USER_ALL && !rebindAllCurrentUsers) {
+            isVisibleBackgroundUser =
+                    mUserManagerInternal.isVisibleBackgroundFullUser(userToRebind);
             userIds = new IntArray(1);
             userIds.add(userToRebind);
         }
@@ -1458,7 +1475,8 @@
 
             // Filter approvedComponentsByUser to collect all of the components that are allowed
             // for the currently active user(s).
-            populateComponentsToBind(componentsToBind, userIds, approvedComponentsByUser);
+            populateComponentsToBind(componentsToBind, userIds, approvedComponentsByUser,
+                    isVisibleBackgroundUser);
 
             // For every current non-system connection, disconnect services that are no longer
             // approved, or ALL services if we are force rebinding
diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java
index 82c5733..1aa5ac0 100644
--- a/services/core/java/com/android/server/notification/ZenLog.java
+++ b/services/core/java/com/android/server/notification/ZenLog.java
@@ -23,18 +23,15 @@
 import android.os.Build;
 import android.os.RemoteException;
 import android.provider.Settings.Global;
-import android.service.notification.Condition;
 import android.service.notification.IConditionProvider;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeDiff;
 import android.util.LocalLog;
-import android.util.Log;
-import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.PrintWriter;
-import java.text.SimpleDateFormat;
-import java.util.Date;
 import java.util.List;
 
 public class ZenLog {
@@ -61,6 +58,8 @@
     private static final int TYPE_RECORD_CALLER = 19;
     private static final int TYPE_CHECK_REPEAT_CALLER = 20;
     private static final int TYPE_ALERT_ON_UPDATED_INTERCEPT = 21;
+    private static final int TYPE_APPLY_DEVICE_EFFECT = 22;
+    private static final int TYPE_SCHEDULE_APPLY_DEVICE_EFFECT = 23;
 
     public static void traceIntercepted(NotificationRecord record, String reason) {
         append(TYPE_INTERCEPTED, record.getKey() + "," + reason);
@@ -173,6 +172,14 @@
                 + ", given uri=" + hasUri);
     }
 
+    public static void traceApplyDeviceEffect(String effect, boolean newValue) {
+        append(TYPE_APPLY_DEVICE_EFFECT, effect + " -> " + newValue);
+    }
+
+    public static void traceScheduleApplyDeviceEffect(String effect, boolean scheduledValue) {
+        append(TYPE_SCHEDULE_APPLY_DEVICE_EFFECT, effect + " -> " + scheduledValue);
+    }
+
     private static String subscribeResult(IConditionProvider provider, RemoteException e) {
         return provider == null ? "no provider" : e != null ? e.getMessage() : "ok";
     }
@@ -196,6 +203,8 @@
             case TYPE_RECORD_CALLER: return "record_caller";
             case TYPE_CHECK_REPEAT_CALLER: return "check_repeat_caller";
             case TYPE_ALERT_ON_UPDATED_INTERCEPT: return "alert_on_updated_intercept";
+            case TYPE_APPLY_DEVICE_EFFECT: return "apply_device_effect";
+            case TYPE_SCHEDULE_APPLY_DEVICE_EFFECT: return "schedule_device_effect";
             default: return "unknown";
         }
     }
@@ -273,4 +282,14 @@
             STATE_CHANGES.dump(prefix, pw);
         }
     }
+
+    @VisibleForTesting(/* otherwise = VisibleForTesting.NONE */)
+    public static void clear() {
+        synchronized (INTERCEPTION_EVENTS) {
+            INTERCEPTION_EVENTS.clear();
+        }
+        synchronized (STATE_CHANGES) {
+            STATE_CHANGES.clear();
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index d374142..9fb9e71 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -42,6 +42,7 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.IntArray;
 import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
 
@@ -981,39 +982,23 @@
     }
 
     int[] queryInstalledUsers(int[] users, boolean installed) {
-        int num = 0;
+        IntArray installedUsers = new IntArray(users.length);
         for (int user : users) {
             if (getInstalled(user) == installed) {
-                num++;
+                installedUsers.add(user);
             }
         }
-        int[] res = new int[num];
-        num = 0;
-        for (int user : users) {
-            if (getInstalled(user) == installed) {
-                res[num] = user;
-                num++;
-            }
-        }
-        return res;
+        return installedUsers.toArray();
     }
 
     int[] queryUsersInstalledOrHasData(int[] users) {
-        int num = 0;
+        IntArray usersInstalledOrHasData = new IntArray(users.length);
         for (int user : users) {
             if (getInstalled(user) || readUserState(user).dataExists()) {
-                num++;
+                usersInstalledOrHasData.add(user);
             }
         }
-        int[] res = new int[num];
-        num = 0;
-        for (int user : users) {
-            if (getInstalled(user) || readUserState(user).dataExists()) {
-                res[num] = user;
-                num++;
-            }
-        }
-        return res;
+        return usersInstalledOrHasData.toArray();
     }
 
     long getCeDataInode(int userId) {
@@ -1283,25 +1268,14 @@
     }
 
     public int[] getNotInstalledUserIds() {
-        int count = 0;
         int userStateCount = mUserStates.size();
+        IntArray notInstalledUsers = new IntArray(userStateCount);
         for (int i = 0; i < userStateCount; i++) {
             if (!mUserStates.valueAt(i).isInstalled()) {
-                count++;
+                notInstalledUsers.add(mUserStates.keyAt(i));
             }
         }
-        if (count == 0) {
-            return EmptyArray.INT;
-        }
-
-        int[] excludedUserIds = new int[count];
-        int idx = 0;
-        for (int i = 0; i < userStateCount; i++) {
-            if (!mUserStates.valueAt(i).isInstalled()) {
-                excludedUserIds[idx++] = mUserStates.keyAt(i);
-            }
-        }
-        return excludedUserIds;
+        return notInstalledUsers.toArray();
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java
index 26da84f..f9a8968 100644
--- a/services/core/java/com/android/server/pm/RemovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java
@@ -292,8 +292,10 @@
         // Step 2: destroy app data.
         mAppDataHelper.destroyAppDataLIF(resolvedPkg, userId, appDataDeletionFlags);
         if (userId != UserHandle.USER_ALL) {
-            ps.setCeDataInode(-1, userId);
-            ps.setDeDataInode(-1, userId);
+            synchronized (mPm.mLock) {
+                ps.setCeDataInode(-1, userId);
+                ps.setDeDataInode(-1, userId);
+            }
         }
 
         final PreferredActivityHelper preferredActivityHelper = new PreferredActivityHelper(mPm,
@@ -425,19 +427,21 @@
             }
             final boolean isArchive = (flags & PackageManager.DELETE_ARCHIVE) != 0;
             final long currentTimeMillis = System.currentTimeMillis();
-            for (int userId : outInfo.mRemovedUsers) {
-                if (DEBUG_REMOVE) {
-                    final boolean wasInstalled = deletedPs.getInstalled(userId);
-                    Slog.d(TAG, "    user " + userId + ": " + wasInstalled + " => " + false);
+            synchronized (mPm.mLock) {
+                for (int userId : outInfo.mRemovedUsers) {
+                    if (DEBUG_REMOVE) {
+                        final boolean wasInstalled = deletedPs.getInstalled(userId);
+                        Slog.d(TAG, "    user " + userId + ": " + wasInstalled + " => " + false);
+                    }
+                    deletedPs.setInstalled(/* installed= */ false, userId);
                 }
-                deletedPs.setInstalled(/* installed= */ false, userId);
-            }
 
-            // Preserve split apk information for downgrade check with DELETE_KEEP_DATA and archived
-            // app cases
-            if (deletedPkg != null && deletedPkg.getSplitNames() != null) {
-                deletedPs.setSplitNames(deletedPkg.getSplitNames());
-                deletedPs.setSplitRevisionCodes(deletedPkg.getSplitRevisionCodes());
+                // Preserve split apk information for downgrade check with DELETE_KEEP_DATA and
+                // archived app cases
+                if (deletedPkg != null && deletedPkg.getSplitNames() != null) {
+                    deletedPs.setSplitNames(deletedPkg.getSplitNames());
+                    deletedPs.setSplitRevisionCodes(deletedPkg.getSplitRevisionCodes());
+                }
             }
         }
 
@@ -448,17 +452,19 @@
             if (DEBUG_REMOVE) {
                 Slog.d(TAG, "Propagating install state across downgrade");
             }
-            for (int userId : allUserHandles) {
-                final boolean installed = ArrayUtils.contains(outInfo.mOrigUsers, userId);
-                if (DEBUG_REMOVE) {
-                    Slog.d(TAG, "    user " + userId + " => " + installed);
-                }
-                if (installed != deletedPs.getInstalled(userId)) {
-                    installedStateChanged = true;
-                }
-                deletedPs.setInstalled(installed, userId);
-                if (installed) {
-                    deletedPs.setUninstallReason(UNINSTALL_REASON_UNKNOWN, userId);
+            synchronized (mPm.mLock) {
+                for (int userId : allUserHandles) {
+                    final boolean installed = ArrayUtils.contains(outInfo.mOrigUsers, userId);
+                    if (DEBUG_REMOVE) {
+                        Slog.d(TAG, "    user " + userId + " => " + installed);
+                    }
+                    if (installed != deletedPs.getInstalled(userId)) {
+                        installedStateChanged = true;
+                    }
+                    deletedPs.setInstalled(installed, userId);
+                    if (installed) {
+                        deletedPs.setUninstallReason(UNINSTALL_REASON_UNKNOWN, userId);
+                    }
                 }
             }
         }
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 6c78b3c..6e7a009 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -1366,7 +1366,7 @@
 
         for (int requestedPermissionNum = 0; requestedPermissionNum < numRequestedPermissions;
                 requestedPermissionNum++) {
-            String permission = requestedPermissions[requestedPermissionNum];
+            String permission = sortedRequestedPermissions[requestedPermissionNum];
 
             // If there is a disabled system app it may request a permission the updated
             // version ot the data partition doesn't, In this case skip the permission.
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index f96706e..749025b 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -16,6 +16,7 @@
 
 package com.android.server.policy;
 
+import static android.Manifest.permission.CREATE_VIRTUAL_DEVICE;
 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
 import static android.Manifest.permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW;
 import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
@@ -59,13 +60,18 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
 import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
 import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
 import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
+import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType;
 import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_KEY_CHORD;
@@ -3058,7 +3064,7 @@
     /** {@inheritDoc} */
     @Override
     public int checkAddPermission(int type, boolean isRoundedCornerOverlay, String packageName,
-            int[] outAppOp) {
+            int[] outAppOp, int displayId) {
         if (isRoundedCornerOverlay && mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW)
                 != PERMISSION_GRANTED) {
             return ADD_PERMISSION_DENIED;
@@ -3098,6 +3104,12 @@
                 case TYPE_VOICE_INTERACTION:
                 case TYPE_QS_DIALOG:
                 case TYPE_NAVIGATION_BAR_PANEL:
+                case TYPE_STATUS_BAR:
+                case TYPE_NOTIFICATION_SHADE:
+                case TYPE_NAVIGATION_BAR:
+                case TYPE_STATUS_BAR_ADDITIONAL:
+                case TYPE_STATUS_BAR_SUB_PANEL:
+                case TYPE_VOICE_INTERACTION_STARTING:
                     // The window manager will check these.
                     return ADD_OKAY;
             }
@@ -3141,6 +3153,13 @@
             return ADD_OKAY;
         }
 
+        // Allow virtual device owners to add overlays on the displays they own.
+        if (mWindowManagerFuncs.isCallerVirtualDeviceOwner(displayId, callingUid)
+                && mContext.checkCallingOrSelfPermission(CREATE_VIRTUAL_DEVICE)
+                == PERMISSION_GRANTED) {
+            return ADD_OKAY;
+        }
+
         // check if user has enabled this operation. SecurityException will be thrown if this app
         // has not been allowed by the user. The reason to use "noteOp" (instead of checkOp) is to
         // make sure the usage is logged.
@@ -3581,18 +3600,6 @@
                 if (down) {
                     int direction = keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP ? 1 : -1;
 
-                    // Disable autobrightness if it's on
-                    int auto = Settings.System.getIntForUser(
-                            mContext.getContentResolver(),
-                            Settings.System.SCREEN_BRIGHTNESS_MODE,
-                            Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
-                            UserHandle.USER_CURRENT_OR_SELF);
-                    if (auto != 0) {
-                        Settings.System.putIntForUser(mContext.getContentResolver(),
-                                Settings.System.SCREEN_BRIGHTNESS_MODE,
-                                Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
-                                UserHandle.USER_CURRENT_OR_SELF);
-                    }
                     int screenDisplayId = displayId < 0 ? DEFAULT_DISPLAY : displayId;
 
                     float minLinearBrightness = mPowerManager.getBrightnessConstraint(
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 989c8a8..892af6b 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -362,6 +362,12 @@
          * Invoked when a screenshot is taken of the given display to notify registered listeners.
          */
         List<ComponentName> notifyScreenshotListeners(int displayId);
+
+        /**
+         * Returns whether the given UID is the owner of a virtual device, which the given display
+         * belongs to.
+         */
+        boolean isCallerVirtualDeviceOwner(int displayId, int callingUid);
     }
 
     /**
@@ -421,6 +427,7 @@
      * @param packageName package name
      * @param outAppOp First element will be filled with the app op corresponding to
      *                 this window, or OP_NONE.
+     * @param displayId The display on which this window is being added.
      *
      * @return {@link WindowManagerGlobal#ADD_OKAY} if the add can proceed;
      *      else an error code, usually
@@ -429,7 +436,7 @@
      * @see WindowManager.LayoutParams#PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY
      */
     int checkAddPermission(int type, boolean isRoundedCornerOverlay, String packageName,
-            int[] outAppOp);
+            int[] outAppOp, int displayId);
 
     /**
      * After the window manager has computed the current configuration based
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index 822ec2e..6847a5c 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -54,6 +54,7 @@
 import android.os.ShellCommand;
 import android.os.SystemClock;
 import android.os.Temperature;
+import android.os.Trace;
 import android.util.ArrayMap;
 import android.util.EventLog;
 import android.util.Slog;
@@ -247,6 +248,7 @@
 
     private void setStatusLocked(int newStatus) {
         if (newStatus != mStatus) {
+            Trace.traceCounter(Trace.TRACE_TAG_POWER, "ThermalManagerService.status", newStatus);
             mStatus = newStatus;
             notifyStatusListenersLocked();
         }
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 67900f8..60b5e65 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -3306,7 +3306,20 @@
         return filteredDisplayName;
     }
 
-    private static final class UserState {
+    private class TvInputManagerCallbackList extends RemoteCallbackList<ITvInputManagerCallback> {
+        @Override
+        public void onCallbackDied(ITvInputManagerCallback callback) {
+            synchronized (mLock) {
+                for (int i = 0; i < mUserStates.size(); i++) {
+                    int userId = mUserStates.keyAt(i);
+                    UserState userState = getOrCreateUserStateLocked(userId);
+                    userState.callbackPidUidMap.remove(callback);
+                }
+            }
+        }
+    }
+
+    private final class UserState {
         // A mapping from the TV input id to its TvInputState.
         private Map<String, TvInputState> inputMap = new HashMap<>();
 
@@ -3327,8 +3340,8 @@
         private final Map<IBinder, SessionState> sessionStateMap = new HashMap<>();
 
         // A list of callbacks.
-        private final RemoteCallbackList<ITvInputManagerCallback> mCallbacks =
-                new RemoteCallbackList<>();
+        private final TvInputManagerCallbackList mCallbacks =
+                new TvInputManagerCallbackList();
 
         private final Map<ITvInputManagerCallback, Pair<Integer, Integer>> callbackPidUidMap =
                 new HashMap<>();
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index 26a6b00..b8ce02ed 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -380,7 +380,16 @@
     public abstract void onPackageAdded(String name, boolean replacing);
     public abstract void onPackageReplaced(ApplicationInfo aInfo);
 
-    public abstract CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai);
+    /** The data for IApplicationThread#bindApplication. */
+    public static final class PreBindInfo {
+        public final @NonNull CompatibilityInfo compatibilityInfo;
+        public final @NonNull Configuration configuration;
+
+        PreBindInfo(@NonNull CompatibilityInfo compatInfo, @NonNull Configuration config) {
+            compatibilityInfo = compatInfo;
+            configuration = config;
+        }
+    }
 
     public final class ActivityTokens {
         private final @NonNull IBinder mActivityToken;
@@ -502,7 +511,9 @@
     public abstract void resumeTopActivities(boolean scheduleIdle);
 
     /** Called by AM just before it binds to an application process. */
-    public abstract void preBindApplication(WindowProcessController wpc);
+    @NonNull
+    public abstract PreBindInfo preBindApplication(@NonNull WindowProcessController wpc,
+            @NonNull ApplicationInfo info);
 
     /** Called by AM when an application process attaches. */
     public abstract boolean attachApplication(WindowProcessController wpc) throws RemoteException;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 3cfb9a07..e25d940d 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -6428,13 +6428,6 @@
         }
 
         @Override
-        public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
-            synchronized (mGlobalLock) {
-                return compatibilityInfoForPackageLocked(ai);
-            }
-        }
-
-        @Override
         public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
                 int requestCode, int resultCode, Intent data) {
             final ActivityRecord r;
@@ -6712,9 +6705,13 @@
 
         @HotPath(caller = HotPath.PROCESS_CHANGE)
         @Override
-        public void preBindApplication(WindowProcessController wpc) {
+        public PreBindInfo preBindApplication(WindowProcessController wpc, ApplicationInfo info) {
             synchronized (mGlobalLockWithoutBoost) {
                 mTaskSupervisor.getActivityMetricsLogger().notifyBindApplication(wpc.mInfo);
+                wpc.onConfigurationChanged(getGlobalConfiguration());
+                // The "info" can be the target of instrumentation.
+                return new PreBindInfo(compatibilityInfoForPackageLocked(info),
+                        new Configuration(wpc.getConfiguration()));
             }
         }
 
@@ -7481,9 +7478,7 @@
                     FEATURE_LEANBACK);
             final boolean isArc = arcFeature != null && arcFeature.version >= 0;
             final boolean isTv = tvFeature != null && tvFeature.version >= 0;
-            sIsPip2ExperimentEnabled = SystemProperties.getBoolean(
-                    "persist.wm_shell.pip2", false)
-                    || (Flags.enablePip2Implementation() && !isArc && !isTv);
+            sIsPip2ExperimentEnabled = Flags.enablePip2() && !isArc && !isTv;
         }
         return sIsPip2ExperimentEnabled;
     }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index e90a2c9..9a3ad2d 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -107,7 +107,6 @@
 import android.app.servertransaction.PauseActivityItem;
 import android.app.servertransaction.ResumeActivityItem;
 import android.app.servertransaction.StopActivityItem;
-import android.companion.virtual.VirtualDeviceManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -158,6 +157,7 @@
 import com.android.server.am.ActivityManagerService;
 import com.android.server.am.HostingRecord;
 import com.android.server.am.UserState;
+import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
 import com.android.server.pm.SaferIntentUtils;
 import com.android.server.utils.Slogf;
 import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
@@ -285,7 +285,7 @@
     private WindowManagerService mWindowManager;
 
     private AppOpsManager mAppOpsManager;
-    private VirtualDeviceManager mVirtualDeviceManager;
+    private VirtualDeviceManagerInternal mVirtualDeviceManagerInternal;
 
     /** Common synchronization logic used to save things to disks. */
     PersisterQueue mPersisterQueue;
@@ -1298,16 +1298,24 @@
         if (displayId == DEFAULT_DISPLAY || displayId == INVALID_DISPLAY)  {
             return Context.DEVICE_ID_DEFAULT;
         }
-        if (mVirtualDeviceManager == null) {
+        if (mVirtualDeviceManagerInternal == null) {
             if (mService.mHasCompanionDeviceSetupFeature) {
-                mVirtualDeviceManager =
-                        mService.mContext.getSystemService(VirtualDeviceManager.class);
+                mVirtualDeviceManagerInternal =
+                        LocalServices.getService(VirtualDeviceManagerInternal.class);
             }
-            if (mVirtualDeviceManager == null) {
+            if (mVirtualDeviceManagerInternal == null) {
                 return Context.DEVICE_ID_DEFAULT;
             }
         }
-        return mVirtualDeviceManager.getDeviceIdForDisplayId(displayId);
+        return mVirtualDeviceManagerInternal.getDeviceIdForDisplayId(displayId);
+    }
+
+    boolean isDeviceOwnerUid(int displayId, int callingUid) {
+        final int deviceId = getDeviceIdForDisplayId(displayId);
+        if (deviceId == Context.DEVICE_ID_DEFAULT || deviceId == Context.DEVICE_ID_INVALID) {
+            return false;
+        }
+        return mVirtualDeviceManagerInternal.getDeviceOwnerUid(deviceId) == callingUid;
     }
 
     private AppOpsManager getAppOpsManager() {
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 28dbc3a..4e4616d 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -339,13 +339,12 @@
                     removedWindowContainer,
                     BackNavigationInfo.typeToString(backType));
 
-            // For now, we only animate when going home, cross task or cross-activity.
             boolean prepareAnimation =
                     (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
                                     || backType == BackNavigationInfo.TYPE_CROSS_TASK
                                     || backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY
                                     || backType == BackNavigationInfo.TYPE_DIALOG_CLOSE)
-                            && adapter != null;
+                            && (adapter != null && adapter.isAnimatable(backType));
 
             if (prepareAnimation) {
                 final AnimationHandler.ScheduleAnimationBuilder builder =
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index d495acb..97d35b9 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3212,15 +3212,13 @@
      * If xPpi or yDpi is equal to {@link #INVALID_DPI}, the values are ignored.
      */
     void setForcedSize(int width, int height, float xDPI, float yDPI) {
-  	// Can't force size higher than the maximal allowed
-        if (mMaxUiWidth > 0 && width > mMaxUiWidth) {
-            final float ratio = mMaxUiWidth / (float) width;
-            height = (int) (height * ratio);
-            width = mMaxUiWidth;
-        }
-
         mIsSizeForced = mInitialDisplayWidth != width || mInitialDisplayHeight != height;
         if (mIsSizeForced) {
+            if (mMaxUiWidth > 0 && width > mMaxUiWidth) {
+                final float ratio = mMaxUiWidth / (float) width;
+                height = (int) (height * ratio);
+                width = mMaxUiWidth;
+            }
             final Point size = getValidForcedSize(width, height);
             width = size.x;
             height = size.y;
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 745b792..5c62120 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1036,7 +1036,7 @@
     /**
      * Check if a window can be added to the system.
      *
-     * Currently enforces that two window types are singletons per display:
+     * Currently enforces that these window types are singletons per display:
      * <ul>
      * <li>{@link WindowManager.LayoutParams#TYPE_STATUS_BAR}</li>
      * <li>{@link WindowManager.LayoutParams#TYPE_NOTIFICATION_SHADE}</li>
@@ -1058,41 +1058,39 @@
             ActivityTaskManagerService.enforceTaskPermission("DisplayPolicy");
         }
 
+        final String systemUiPermission =
+                mService.isCallerVirtualDeviceOwner(mDisplayContent.getDisplayId(), callingUid)
+                        // Allow virtual device owners to add system windows on their displays.
+                        ? android.Manifest.permission.CREATE_VIRTUAL_DEVICE
+                        : android.Manifest.permission.STATUS_BAR_SERVICE;
+
         switch (attrs.type) {
             case TYPE_STATUS_BAR:
-                mContext.enforcePermission(
-                        android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
+                mContext.enforcePermission(systemUiPermission, callingPid, callingUid,
                         "DisplayPolicy");
                 if (mStatusBar != null && mStatusBar.isAlive()) {
                     return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
                 }
                 break;
             case TYPE_NOTIFICATION_SHADE:
-                mContext.enforcePermission(
-                        android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
+                mContext.enforcePermission(systemUiPermission, callingPid, callingUid,
                         "DisplayPolicy");
-                if (mNotificationShade != null) {
-                    if (mNotificationShade.isAlive()) {
-                        return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
-                    }
+                if (mNotificationShade != null && mNotificationShade.isAlive()) {
+                    return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
                 }
                 break;
             case TYPE_NAVIGATION_BAR:
-                mContext.enforcePermission(android.Manifest.permission.STATUS_BAR_SERVICE,
-                        callingPid, callingUid, "DisplayPolicy");
+                mContext.enforcePermission(systemUiPermission, callingPid, callingUid,
+                        "DisplayPolicy");
                 if (mNavigationBar != null && mNavigationBar.isAlive()) {
                     return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
                 }
                 break;
             case TYPE_NAVIGATION_BAR_PANEL:
-                mContext.enforcePermission(android.Manifest.permission.STATUS_BAR_SERVICE,
-                        callingPid, callingUid, "DisplayPolicy");
-                break;
             case TYPE_STATUS_BAR_ADDITIONAL:
             case TYPE_STATUS_BAR_SUB_PANEL:
             case TYPE_VOICE_INTERACTION_STARTING:
-                mContext.enforcePermission(
-                        android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
+                mContext.enforcePermission(systemUiPermission, callingPid, callingUid,
                         "DisplayPolicy");
                 break;
             case TYPE_STATUS_BAR_PANEL:
@@ -1102,8 +1100,7 @@
         if (attrs.providedInsets != null) {
             // Recents component is allowed to add inset types.
             if (!mService.mAtmService.isCallerRecents(callingUid)) {
-                mContext.enforcePermission(
-                        android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
+                mContext.enforcePermission(systemUiPermission, callingPid, callingUid,
                         "DisplayPolicy");
             }
         }
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index f40f2617..e585efa 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -69,6 +69,7 @@
         mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
     }
 
+    /** Stores the size override settings. If the width or height is zero, it means to clear. */
     void setForcedSize(@NonNull DisplayContent displayContent, int width, int height) {
         if (displayContent.isDefaultDisplay) {
             final String sizeString = (width == 0 || height == 0) ? "" : (width + "," + height);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 90b9a04..fb57a1b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1524,7 +1524,7 @@
         final boolean isRoundedCornerOverlay = (attrs.privateFlags
                 & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0;
         int res = mPolicy.checkAddPermission(attrs.type, isRoundedCornerOverlay, attrs.packageName,
-                appOp);
+                appOp, displayId);
         if (res != ADD_OKAY) {
             return res;
         }
@@ -6023,7 +6023,7 @@
                     displayContent.setForcedSize(displayContent.mInitialDisplayWidth,
                             displayContent.mInitialDisplayHeight,
                             displayContent.mInitialPhysicalXDpi,
-                            displayContent.mInitialPhysicalXDpi);
+                            displayContent.mInitialPhysicalYDpi);
                 }
             }
         } finally {
@@ -10121,6 +10121,23 @@
         }
     }
 
+    /**
+     * Returns whether the given UID is the owner of a virtual device, which the given display
+     * belongs to.
+     */
+    @Override
+    public boolean isCallerVirtualDeviceOwner(int displayId, int callingUid) {
+        if (!android.companion.virtualdevice.flags.Flags.statusBarAndInsets()) {
+            return false;
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return mAtmService.mTaskSupervisor.isDeviceOwnerUid(displayId, callingUid);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
     @RequiresPermission(ACCESS_SURFACE_FLINGER)
     @Override
     public boolean replaceContentOnDisplay(int displayId, SurfaceControl sc) {
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 2957504..87ce866 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -358,7 +358,6 @@
         mUseFifoUiScheduling = com.android.window.flags.Flags.fifoPriorityForMajorUiProcesses()
                 && (isSysUiPackage || mAtm.isCallerRecents(uid));
 
-        onConfigurationChanged(atm.getGlobalConfiguration());
         mAtm.mPackageConfigPersister.updateConfigIfNeeded(this, mUserId, mInfo.packageName);
     }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index fc61967..470025a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -7151,9 +7151,7 @@
 
         // If there is a profile owner, redirect to that; otherwise query the device owner.
         ComponentName aliasChooser = getProfileOwnerAsUser(caller.getUserId());
-        boolean isDoUser = Flags.headlessSingleUserFixes()
-                ? caller.getUserId() == getDeviceOwnerUserId()
-                : caller.getUserHandle().isSystem();
+        boolean isDoUser = caller.getUserId() == getDeviceOwnerUserId();
         if (aliasChooser == null && isDoUser) {
             synchronized (getLockObject()) {
                 final ActiveAdmin deviceOwnerAdmin = getDeviceOwnerAdminLocked();
@@ -8163,7 +8161,7 @@
             // First check whether the admin is allowed to wipe the device/user/profile.
             final String restriction;
             boolean shouldFactoryReset = userId == UserHandle.USER_SYSTEM;
-            if (Flags.headlessSingleUserFixes() && getHeadlessDeviceOwnerModeForDeviceOwner()
+            if (getHeadlessDeviceOwnerModeForDeviceOwner()
                     == HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER) {
                 shouldFactoryReset = userId == getMainUserId();
             }
@@ -8187,8 +8185,7 @@
                 adminPackage,
                 userId)) {
             // Legacy mode
-            wipeDevice = Flags.headlessSingleUserFixes()
-                    && getHeadlessDeviceOwnerModeForDeviceOwner()
+            wipeDevice = getHeadlessDeviceOwnerModeForDeviceOwner()
                     == HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER ? isMainUser : isSystemUser;
         } else {
             // Explicit behaviour
@@ -11858,7 +11855,7 @@
             }
             setBackwardsCompatibleAppRestrictions(
                     caller, packageName, restrictions, caller.getUserHandle());
-        } else if (Flags.dmrhSetAppRestrictions()) {
+        } else {
             final boolean isRoleHolder;
             if (who != null) {
                 // DO or PO
@@ -11905,15 +11902,6 @@
                             caller.getUserHandle());
                 });
             }
-        } else {
-            Preconditions.checkCallAuthorization((caller.hasAdminComponent()
-                    && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
-                    || (caller.hasPackage() && isCallerDelegate(caller,
-                    DELEGATION_APP_RESTRICTIONS)));
-            mInjector.binderWithCleanCallingIdentity(() -> {
-                mUserManager.setApplicationRestrictions(packageName, restrictions,
-                        caller.getUserHandle());
-            });
         }
 
         DevicePolicyEventLogger
@@ -13244,7 +13232,7 @@
                 return Bundle.EMPTY;
             }
             return policies.get(enforcingAdmin).getValue();
-        } else if (Flags.dmrhSetAppRestrictions()) {
+        } else {
             final boolean isRoleHolder;
             if (who != null) {
                 // Caller is DO or PO. They cannot call this on parent
@@ -13287,19 +13275,6 @@
                     return bundle != null ? bundle : Bundle.EMPTY;
                 });
             }
-
-        } else {
-            Preconditions.checkCallAuthorization((caller.hasAdminComponent()
-                    && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
-                    || (caller.hasPackage() && isCallerDelegate(caller,
-                    DELEGATION_APP_RESTRICTIONS)));
-            return mInjector.binderWithCleanCallingIdentity(() -> {
-                Bundle bundle = mUserManager.getApplicationRestrictions(packageName,
-                        caller.getUserHandle());
-                // if no restrictions were saved, mUserManager.getApplicationRestrictions
-                // returns null, but DPM method should return an empty Bundle as per JavaDoc
-                return bundle != null ? bundle : Bundle.EMPTY;
-            });
         }
     }
 
@@ -18662,8 +18637,7 @@
 
         // Backup service has to be enabled on the main user in order for it to be enabled on
         // secondary users.
-        if (Flags.headlessSingleUserFixes() && isDeviceOwner(caller)
-                && getHeadlessDeviceOwnerModeForDeviceOwner()
+        if (isDeviceOwner(caller) && getHeadlessDeviceOwnerModeForDeviceOwner()
                 == HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER) {
             toggleBackupServiceActive(UserHandle.USER_SYSTEM, enabled);
         }
diff --git a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
index 7ed23cd..d2c91ff 100644
--- a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
@@ -888,7 +888,7 @@
                     val mayGrantByPrivileged =
                         !permission.isPrivileged ||
                             requestingPackageStates.anyIndexed { _, it ->
-                                checkPrivilegedPermissionAllowlist(it, permission)
+                                checkPrivilegedPermissionAllowlistIfNeeded(it, permission)
                             }
                     val shouldGrantBySignature =
                         permission.isSignature &&
@@ -1280,7 +1280,16 @@
         }
     }
 
-    private fun MutateStateScope.checkPrivilegedPermissionAllowlist(
+    /**
+     * We only check privileged permission allowlist for system privileged apps. Hence, for platform
+     * or for normal apps, we return true to indicate that we don't need to check the allowlist and
+     * will let follow-up checks to decide whether we should grant the permission.
+     *
+     * @return `true`, if the permission is allowlisted for system privileged apps, or if we
+     *         don't need to check the allowlist (for platform or for normal apps).
+     *         `false`, if the permission is not allowlisted for system privileged apps.
+     */
+    private fun MutateStateScope.checkPrivilegedPermissionAllowlistIfNeeded(
         packageState: PackageState,
         permission: Permission
     ): Boolean {
diff --git a/services/tests/InputMethodSystemServerTests/Android.bp b/services/tests/InputMethodSystemServerTests/Android.bp
index 3bce9b5..9044259 100644
--- a/services/tests/InputMethodSystemServerTests/Android.bp
+++ b/services/tests/InputMethodSystemServerTests/Android.bp
@@ -138,3 +138,17 @@
         enabled: false,
     },
 }
+
+test_module_config {
+    name: "FrameworksInputMethodSystemServerTests_server_inputmethod",
+    base: "FrameworksInputMethodSystemServerTests",
+    test_suites: ["device-tests"],
+    include_filters: ["com.android.server.inputmethod"],
+}
+
+test_module_config {
+    name: "FrameworksImeTests_android_inputmethodservice",
+    base: "FrameworksImeTests",
+    test_suites: ["device-tests"],
+    include_filters: ["com.android.inputmethodservice"],
+}
diff --git a/services/tests/PackageManagerServiceTests/host/Android.bp b/services/tests/PackageManagerServiceTests/host/Android.bp
index 6fd21f7..75db316 100644
--- a/services/tests/PackageManagerServiceTests/host/Android.bp
+++ b/services/tests/PackageManagerServiceTests/host/Android.bp
@@ -88,3 +88,10 @@
         " && $(location soong_zip) -o $(genDir)/temp.apk -L 0 -C $(genDir)/apk -D $(genDir)/apk" +
         " && $(location zipalign) -f 4 $(genDir)/temp.apk $(out)",
 }
+
+test_module_config_host {
+    name: "PackageManagerServiceHostTests_test_overlayactorvisibilitytest",
+    base: "PackageManagerServiceHostTests",
+    test_suites: ["device-tests"],
+    include_filters: ["com.android.server.pm.test.OverlayActorVisibilityTest"],
+}
diff --git a/services/tests/PackageManagerServiceTests/server/Android.bp b/services/tests/PackageManagerServiceTests/server/Android.bp
index 598e273..e26213e 100644
--- a/services/tests/PackageManagerServiceTests/server/Android.bp
+++ b/services/tests/PackageManagerServiceTests/server/Android.bp
@@ -164,3 +164,25 @@
         "done && " +
         "$(location soong_zip) -o $(out) -C $(genDir)/res -D $(genDir)/res",
 }
+
+test_module_config {
+    name: "PackageManagerServiceServerTests_server_pm_Presubmit",
+    base: "PackageManagerServiceServerTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.pm."],
+    include_annotations: ["android.platform.test.annotations.Presubmit"],
+}
+
+test_module_config {
+    name: "PackageManagerServiceServerTests_server_pm_Postsubmit",
+    base: "PackageManagerServiceServerTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.pm."],
+    include_annotations: ["android.platform.test.annotations.Postsubmit"],
+}
diff --git a/services/tests/PackageManagerServiceTests/unit/Android.bp b/services/tests/PackageManagerServiceTests/unit/Android.bp
index c93f482..db88b16 100644
--- a/services/tests/PackageManagerServiceTests/unit/Android.bp
+++ b/services/tests/PackageManagerServiceTests/unit/Android.bp
@@ -47,3 +47,10 @@
     platform_apis: true,
     test_suites: ["device-tests"],
 }
+
+test_module_config {
+    name: "PackageManagerServiceUnitTests_verify_domain",
+    base: "PackageManagerServiceUnitTests",
+    test_suites: ["device-tests"],
+    include_filters: ["com.android.server.pm.test.verify.domain"],
+}
diff --git a/services/tests/displayservicetests/Android.bp b/services/tests/displayservicetests/Android.bp
index 3bafe72..61350bf 100644
--- a/services/tests/displayservicetests/Android.bp
+++ b/services/tests/displayservicetests/Android.bp
@@ -56,3 +56,13 @@
         enabled: false,
     },
 }
+
+test_module_config {
+    name: "DisplayServiceTests_server_display",
+    base: "DisplayServiceTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.display"],
+}
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 026fcc4..5bb8ded 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -64,6 +64,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityManagerInternal;
 import android.app.ActivityOptions.LaunchCookie;
 import android.app.PropertyInvalidatedCache;
 import android.companion.virtual.IVirtualDevice;
@@ -358,6 +359,7 @@
     @Mock DisplayDeviceConfig mMockDisplayDeviceConfig;
     @Mock PackageManagerInternal mMockPackageManagerInternal;
     @Mock DisplayManagerInternal mMockDisplayManagerInternal;
+    @Mock ActivityManagerInternal mMockActivityManagerInternal;
     @Mock DisplayAdapter mMockDisplayAdapter;
 
     @Captor ArgumentCaptor<ContentRecordingSession> mContentRecordingSessionCaptor;
@@ -388,6 +390,8 @@
                 PackageManagerInternal.class, mMockPackageManagerInternal);
         mLocalServiceKeeperRule.overrideLocalService(
                 DisplayManagerInternal.class, mMockDisplayManagerInternal);
+        mLocalServiceKeeperRule.overrideLocalService(
+                ActivityManagerInternal.class, mMockActivityManagerInternal);
         Display display = mock(Display.class);
         when(display.getDisplayAdjustments()).thenReturn(new DisplayAdjustments());
         when(display.getBrightnessInfo()).thenReturn(mock(BrightnessInfo.class));
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayOffloadSessionImplTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayOffloadSessionImplTest.java
index 30c384a..5e868a3 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayOffloadSessionImplTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayOffloadSessionImplTest.java
@@ -38,7 +38,7 @@
     private DisplayManagerInternal.DisplayOffloader mDisplayOffloader;
 
     @Mock
-    private DisplayPowerControllerInterface mDisplayPowerController;
+    private DisplayPowerController mDisplayPowerController;
 
     private DisplayOffloadSessionImpl mSession;
 
diff --git a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
index a7e0ebd..120cc84 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -118,7 +118,7 @@
     @Mock
     private DisplayManagerFlags mFlags;
     @Mock
-    private DisplayPowerControllerInterface mMockedDisplayPowerController;
+    private DisplayPowerController mMockedDisplayPowerController;
 
     private Handler mHandler;
 
diff --git a/services/tests/dreamservicetests/Android.bp b/services/tests/dreamservicetests/Android.bp
index 6369d45..1f0e975 100644
--- a/services/tests/dreamservicetests/Android.bp
+++ b/services/tests/dreamservicetests/Android.bp
@@ -42,3 +42,13 @@
         enabled: false,
     },
 }
+
+test_module_config {
+    name: "DreamServiceTests_server_dreams",
+    base: "DreamServiceTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.dreams"],
+}
diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp
index 9808d54..5a76931 100644
--- a/services/tests/mockingservicestests/Android.bp
+++ b/services/tests/mockingservicestests/Android.bp
@@ -333,3 +333,73 @@
     test_suites: ["device-tests"],
     include_filters: ["com.android.server.utils"],
 }
+
+test_module_config {
+    name: "FrameworksMockingServicesTests_android_server",
+    base: "FrameworksMockingServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server"],
+}
+
+test_module_config {
+    name: "FrameworksMockingServicesTests_server_job",
+    base: "FrameworksMockingServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.job"],
+}
+
+test_module_config {
+    name: "FrameworksMockingServicesTests_server_tare",
+    base: "FrameworksMockingServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.tare"],
+}
+
+test_module_config {
+    name: "FrameworksMockingServicesTests_server_backup",
+    base: "FrameworksMockingServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.backup"],
+}
+
+test_module_config {
+    name: "FrameworksMockingServicesTests_server_rescuepartytest",
+    base: "FrameworksMockingServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.RescuePartyTest"],
+}
+
+test_module_config {
+    name: "FrameworksMockingServicesTests_server_power",
+    base: "FrameworksMockingServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.power"],
+}
+
+test_module_config {
+    name: "FrameworksMockingServicesTests_server_trust",
+    base: "FrameworksMockingServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.trust"],
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 51aa528..3b284a2 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -90,7 +90,6 @@
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.app.ApplicationExitInfo;
-import android.app.IApplicationThread;
 import android.app.IServiceConnection;
 import android.content.ComponentName;
 import android.content.Context;
@@ -164,6 +163,10 @@
 
     private static int sFirstCachedAdj = ProcessList.CACHED_APP_MIN_ADJ
             + ProcessList.CACHED_APP_IMPORTANCE_LEVELS;
+    private static int sFirstUiCachedAdj = ProcessList.CACHED_APP_MIN_ADJ + 10;
+    private static int sFirstNonUiCachedAdj = ProcessList.CACHED_APP_MIN_ADJ + 20;
+    private static int sUiTierSize = 5;
+
     private Context mContext;
     private PackageManagerInternal mPackageManagerInternal;
     private ActivityManagerService mService;
@@ -232,9 +235,6 @@
                         mInjector);
         mService.mOomAdjuster.mAdjSeq = 10000;
         mService.mWakefulness = new AtomicInteger(PowerManagerInternal.WAKEFULNESS_AWAKE);
-        if (mService.mConstants.USE_TIERED_CACHED_ADJ) {
-            sFirstCachedAdj = ProcessList.CACHED_APP_MIN_ADJ + 10;
-        }
         mSetFlagsRule.enableFlags(Flags.FLAG_NEW_FGS_RESTRICTION_LOGIC);
     }
 
@@ -473,7 +473,8 @@
         mService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
         updateOomAdj(app);
 
-        final int expectedAdj = sFirstCachedAdj;
+        final int expectedAdj = mService.mConstants.USE_TIERED_CACHED_ADJ
+                ? sFirstUiCachedAdj : sFirstCachedAdj;
         assertProcStates(app, PROCESS_STATE_CACHED_EMPTY, expectedAdj,
                 SCHED_GROUP_BACKGROUND);
     }
@@ -701,7 +702,9 @@
             mInjector.jumpUptimeAheadTo(followUpTimeCaptor.getValue());
             mService.mOomAdjuster.updateOomAdjFollowUpTargetsLocked();
 
-            assertEquals(sFirstCachedAdj, app.mState.getSetAdj());
+            final int expectedAdj = mService.mConstants.USE_TIERED_CACHED_ADJ
+                    ? sFirstUiCachedAdj : sFirstCachedAdj;
+            assertEquals(expectedAdj, app.mState.getSetAdj());
             // Follow up should not have been called again.
             verify(mService.mHandler).sendEmptyMessageAtTime(eq(FOLLOW_UP_OOMADJUSTER_UPDATE_MSG),
                     followUpTimeCaptor.capture());
@@ -836,7 +839,9 @@
         mInjector.jumpUptimeAheadTo(followUpTimeCaptor.getValue());
         mService.mOomAdjuster.updateOomAdjFollowUpTargetsLocked();
 
-        assertProcStates(app, PROCESS_STATE_LAST_ACTIVITY, CACHED_APP_MIN_ADJ,
+        int expectedAdj = mService.mConstants.USE_TIERED_CACHED_ADJ
+                ? sFirstUiCachedAdj : CACHED_APP_MIN_ADJ;
+        assertProcStates(app, PROCESS_STATE_LAST_ACTIVITY, expectedAdj,
                 SCHED_GROUP_BACKGROUND, "previous-expired");
         // Follow up should not have been called again.
         verify(mService.mHandler).sendEmptyMessageAtTime(eq(FOLLOW_UP_OOMADJUSTER_UPDATE_MSG),
@@ -877,9 +882,15 @@
 
         for (int i = 0; i < numberOfApps; i++) {
             final int mruIndex = numberOfApps - i - 1;
-            int expectedAdj = CACHED_APP_MIN_ADJ + (mruIndex * 2 * CACHED_APP_IMPORTANCE_LEVELS);
-            if (expectedAdj > CACHED_APP_MAX_ADJ) {
-                expectedAdj = CACHED_APP_MAX_ADJ;
+            int expectedAdj;
+            if (mService.mConstants.USE_TIERED_CACHED_ADJ) {
+                expectedAdj = (i < numberOfApps - sUiTierSize)
+                        ? sFirstNonUiCachedAdj : sFirstUiCachedAdj + mruIndex;
+            } else {
+                expectedAdj = CACHED_APP_MIN_ADJ + (mruIndex * 2 * CACHED_APP_IMPORTANCE_LEVELS);
+                if (expectedAdj > CACHED_APP_MAX_ADJ) {
+                    expectedAdj = CACHED_APP_MAX_ADJ;
+                }
             }
             assertProcStates(apps[i], PROCESS_STATE_LAST_ACTIVITY, expectedAdj,
                     SCHED_GROUP_BACKGROUND, "previous-expired");
@@ -1003,7 +1014,9 @@
         updateOomAdj(client, app);
         doReturn(null).when(mService).getTopApp();
 
-        assertProcStates(app, PROCESS_STATE_SERVICE, sFirstCachedAdj, SCHED_GROUP_BACKGROUND);
+        final int expectedAdj = mService.mConstants.USE_TIERED_CACHED_ADJ
+                ? sFirstUiCachedAdj : sFirstCachedAdj;
+        assertProcStates(app, PROCESS_STATE_SERVICE, expectedAdj, SCHED_GROUP_BACKGROUND);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1053,7 +1066,9 @@
         mService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
         updateOomAdj(app);
 
-        assertProcStates(app, PROCESS_STATE_CACHED_EMPTY, sFirstCachedAdj, SCHED_GROUP_BACKGROUND);
+        final int expectedAdj = mService.mConstants.USE_TIERED_CACHED_ADJ
+                ? sFirstNonUiCachedAdj : sFirstCachedAdj;
+        assertProcStates(app, PROCESS_STATE_CACHED_EMPTY, expectedAdj, SCHED_GROUP_BACKGROUND);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1469,7 +1484,9 @@
         bindProvider(app, app, null, null, false);
         updateOomAdj(app);
 
-        assertProcStates(app, PROCESS_STATE_CACHED_EMPTY, sFirstCachedAdj, SCHED_GROUP_BACKGROUND);
+        final int expectedAdj = mService.mConstants.USE_TIERED_CACHED_ADJ
+                ? sFirstNonUiCachedAdj : sFirstCachedAdj;
+        assertProcStates(app, PROCESS_STATE_CACHED_EMPTY, expectedAdj, SCHED_GROUP_BACKGROUND);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1484,7 +1501,9 @@
         mService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
         updateOomAdj(app, client);
 
-        assertProcStates(app, PROCESS_STATE_CACHED_EMPTY, sFirstCachedAdj, SCHED_GROUP_BACKGROUND);
+        final int expectedAdj = mService.mConstants.USE_TIERED_CACHED_ADJ
+                ? sFirstNonUiCachedAdj : sFirstCachedAdj;
+        assertProcStates(app, PROCESS_STATE_CACHED_EMPTY, expectedAdj, SCHED_GROUP_BACKGROUND);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1592,7 +1611,9 @@
         mInjector.jumpUptimeAheadTo(followUpTimeCaptor.getValue());
         mService.mOomAdjuster.updateOomAdjFollowUpTargetsLocked();
 
-        assertProcStates(app, PROCESS_STATE_CACHED_EMPTY, sFirstCachedAdj, SCHED_GROUP_BACKGROUND,
+        final int expectedAdj = mService.mConstants.USE_TIERED_CACHED_ADJ
+                ? sFirstNonUiCachedAdj : sFirstCachedAdj;
+        assertProcStates(app, PROCESS_STATE_CACHED_EMPTY, expectedAdj, SCHED_GROUP_BACKGROUND,
                 "cch-empty");
         // Follow up should not have been called again.
         verify(mService.mHandler).sendEmptyMessageAtTime(eq(FOLLOW_UP_OOMADJUSTER_UPDATE_MSG),
@@ -2623,12 +2644,11 @@
                 MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
         final int userOwner = 0;
         final int userOther = 1;
-        final int cachedAdj1 = mService.mConstants.USE_TIERED_CACHED_ADJ
-                ? CACHED_APP_MIN_ADJ + 10
-                : CACHED_APP_MIN_ADJ + ProcessList.CACHED_APP_IMPORTANCE_LEVELS;
-        final int cachedAdj2 = mService.mConstants.USE_TIERED_CACHED_ADJ
-                ? CACHED_APP_MIN_ADJ + 10
-                : cachedAdj1 + ProcessList.CACHED_APP_IMPORTANCE_LEVELS * 2;
+
+        // cachedAdj1 and cachedAdj2 will be read if USE_TIERED_CACHED_ADJ is disabled. Otherwise,
+        // sFirstUiCachedAdj and sFirstNonUiCachedAdj are used instead.
+        final int cachedAdj1 = CACHED_APP_MIN_ADJ + ProcessList.CACHED_APP_IMPORTANCE_LEVELS;
+        final int cachedAdj2 = cachedAdj1 + ProcessList.CACHED_APP_IMPORTANCE_LEVELS * 2;
         doReturn(userOwner).when(mService.mUserController).getCurrentUserId();
 
         final ArrayList<ProcessRecord> lru = mService.mProcessList.getLruProcessesLOSP();
@@ -2669,8 +2689,12 @@
         mService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
         updateOomAdj();
 
-        assertProcStates(app, true, PROCESS_STATE_SERVICE, cachedAdj1, "cch-started-ui-services");
-        assertProcStates(app2, true, PROCESS_STATE_SERVICE, cachedAdj2, "cch-started-services");
+        assertProcStates(app, true, PROCESS_STATE_SERVICE,
+                mService.mConstants.USE_TIERED_CACHED_ADJ ? sFirstUiCachedAdj : cachedAdj1,
+                "cch-started-ui-services");
+        assertProcStates(app2, true, PROCESS_STATE_SERVICE,
+                mService.mConstants.USE_TIERED_CACHED_ADJ ? sFirstNonUiCachedAdj : cachedAdj2,
+                "cch-started-services");
 
         app.mState.setSetProcState(PROCESS_STATE_NONEXISTENT);
         app.mState.setAdjType(null);
@@ -2686,7 +2710,10 @@
         s.lastActivity = now - mService.mConstants.MAX_SERVICE_INACTIVITY - 1;
         updateOomAdj();
 
-        assertProcStates(app, true, PROCESS_STATE_SERVICE, cachedAdj1, "cch-started-services");
+        // hasShownUi was set to false for 'app', so 920 is expected for USE_TIERED_CACHED_ADJ.
+        assertProcStates(app, true, PROCESS_STATE_SERVICE,
+                mService.mConstants.USE_TIERED_CACHED_ADJ ? sFirstNonUiCachedAdj : cachedAdj1,
+                "cch-started-services");
 
         app.mServices.stopService(s);
         app.mState.setSetProcState(PROCESS_STATE_NONEXISTENT);
@@ -2705,7 +2732,9 @@
         updateOomAdj();
 
         assertProcStates(app, false, PROCESS_STATE_SERVICE, SERVICE_ADJ, "started-services");
-        assertProcStates(app2, true, PROCESS_STATE_SERVICE, cachedAdj1, "cch-started-services");
+        assertProcStates(app2, true, PROCESS_STATE_SERVICE,
+                mService.mConstants.USE_TIERED_CACHED_ADJ ? sFirstNonUiCachedAdj : cachedAdj1,
+                "cch-started-services");
 
         app.mState.setSetProcState(PROCESS_STATE_NONEXISTENT);
         app.mState.setAdjType(null);
@@ -2715,13 +2744,17 @@
         updateOomAdj();
 
         assertProcStates(app, false, PROCESS_STATE_SERVICE, SERVICE_ADJ, "started-services");
-        assertProcStates(app2, true, PROCESS_STATE_SERVICE, cachedAdj1, "cch-started-services");
+        assertProcStates(app2, true, PROCESS_STATE_SERVICE,
+                mService.mConstants.USE_TIERED_CACHED_ADJ ? sFirstNonUiCachedAdj : cachedAdj1,
+                "cch-started-services");
 
         doReturn(userOther).when(mService.mUserController).getCurrentUserId();
         mService.mOomAdjuster.handleUserSwitchedLocked();
 
         updateOomAdj();
-        assertProcStates(app, true, PROCESS_STATE_SERVICE, cachedAdj1, "cch-started-services");
+        assertProcStates(app, true, PROCESS_STATE_SERVICE,
+                mService.mConstants.USE_TIERED_CACHED_ADJ ? sFirstNonUiCachedAdj : cachedAdj1,
+                "cch-started-services");
         assertProcStates(app2, false, PROCESS_STATE_SERVICE, SERVICE_ADJ, "started-services");
     }
 
@@ -2998,7 +3031,9 @@
         mInjector.jumpUptimeAheadTo(followUpTimeCaptor.getValue());
         mService.mOomAdjuster.updateOomAdjFollowUpTargetsLocked();
 
-        assertProcStates(app, PROCESS_STATE_SERVICE, sFirstCachedAdj, SCHED_GROUP_BACKGROUND,
+        final int expectedAdj = mService.mConstants.USE_TIERED_CACHED_ADJ
+                ? sFirstNonUiCachedAdj : sFirstCachedAdj;
+        assertProcStates(app, PROCESS_STATE_SERVICE, expectedAdj, SCHED_GROUP_BACKGROUND,
                 "cch-started-services");
         // Follow up should not have been called again.
         verify(mService.mHandler).sendEmptyMessageAtTime(eq(FOLLOW_UP_OOMADJUSTER_UPDATE_MSG),
@@ -3031,14 +3066,16 @@
         mInjector.jumpUptimeAheadTo(followUpTimeCaptor.getValue());
         mService.mOomAdjuster.updateOomAdjFollowUpTargetsLocked();
 
-        assertProcStates(app1, PROCESS_STATE_CACHED_EMPTY, sFirstCachedAdj, SCHED_GROUP_BACKGROUND,
+        final int expectedAdj = mService.mConstants.USE_TIERED_CACHED_ADJ
+                ? sFirstNonUiCachedAdj : sFirstCachedAdj;
+        assertProcStates(app1, PROCESS_STATE_CACHED_EMPTY, expectedAdj, SCHED_GROUP_BACKGROUND,
                 "cch-empty");
 
         verify(mService.mHandler, atLeastOnce()).sendEmptyMessageAtTime(
                 eq(FOLLOW_UP_OOMADJUSTER_UPDATE_MSG), followUpTimeCaptor.capture());
         mInjector.jumpUptimeAheadTo(followUpTimeCaptor.getValue());
         mService.mOomAdjuster.updateOomAdjFollowUpTargetsLocked();
-        assertProcStates(app2, PROCESS_STATE_CACHED_EMPTY, sFirstCachedAdj, SCHED_GROUP_BACKGROUND,
+        assertProcStates(app2, PROCESS_STATE_CACHED_EMPTY, expectedAdj, SCHED_GROUP_BACKGROUND,
                 "cch-empty");
     }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp b/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp
index e94b8ad..6a16d1e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp
+++ b/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp
@@ -54,3 +54,13 @@
         "automotive-tests",
     ],
 }
+
+test_module_config {
+    name: "RollbackPackageHealthObserverTests_server_rollback",
+    base: "RollbackPackageHealthObserverTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.rollback"],
+}
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 7d04470..b2ca991 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
@@ -631,7 +631,7 @@
         CountDownLatch stopLatch2 = new CountDownLatch(1);
         // negative value used for test only to avoid conflicting with any real thread that exists
         int isoProc1 = -100;
-        int isoProc2 = 9999;
+        int isoProc2 = 99999999;
         when(mAmInternalMock.getIsolatedProcesses(eq(UID))).thenReturn(List.of(0));
         int[] tids2 = createThreads(threadCount, stopLatch2);
         int[] tids2WithIsolated = Arrays.copyOf(tids2, tids2.length + 2);
@@ -658,7 +658,7 @@
         verify(mNativeWrapperMock, never()).halSetThreads(eq(sessionPtr1), any());
         verify(mNativeWrapperMock, never()).halSetThreads(eq(sessionPtr2), any());
         // the new TIDs pending list should be updated
-        assertArrayEquals(session2.getTidsInternal(), expectedTids2);
+        assertArrayEquals(expectedTids2, session2.getTidsInternal());
         reset(mNativeWrapperMock);
 
         // this should resume and update the threads so those never-existed invalid isolated
@@ -713,8 +713,8 @@
         // in background, set threads for session 1 then it should not be force paused next time
         session1.setThreads(SESSION_TIDS_A);
         // the new TIDs pending list should be updated
-        assertArrayEquals(session1.getTidsInternal(), SESSION_TIDS_A);
-        assertArrayEquals(session2.getTidsInternal(), expectedTids2);
+        assertArrayEquals(SESSION_TIDS_A, session1.getTidsInternal());
+        assertArrayEquals(expectedTids2, session2.getTidsInternal());
         verifyAllHintsEnabled(session1, false);
         verifyAllHintsEnabled(session2, false);
         reset(mNativeWrapperMock);
diff --git a/services/tests/powerservicetests/Android.bp b/services/tests/powerservicetests/Android.bp
index 729dcbd..f8cc6d0 100644
--- a/services/tests/powerservicetests/Android.bp
+++ b/services/tests/powerservicetests/Android.bp
@@ -44,3 +44,13 @@
         enabled: false,
     },
 }
+
+test_module_config {
+    name: "PowerServiceTests_server_power",
+    base: "PowerServiceTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.power"],
+}
diff --git a/services/tests/powerstatstests/Android.bp b/services/tests/powerstatstests/Android.bp
index 91c62be..0e922ce 100644
--- a/services/tests/powerstatstests/Android.bp
+++ b/services/tests/powerstatstests/Android.bp
@@ -79,3 +79,23 @@
     ],
     auto_gen_config: true,
 }
+
+test_module_config {
+    name: "PowerStatsTests_stats_bstatscputimesvalidationtest",
+    base: "PowerStatsTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.power.stats.BstatsCpuTimesValidationTest"],
+}
+
+test_module_config {
+    name: "PowerStatsTests_power_stats",
+    base: "PowerStatsTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.power.stats"],
+}
diff --git a/services/tests/powerstatstests/TEST_MAPPING b/services/tests/powerstatstests/TEST_MAPPING
index fb24361..1e8d2de 100644
--- a/services/tests/powerstatstests/TEST_MAPPING
+++ b/services/tests/powerstatstests/TEST_MAPPING
@@ -14,8 +14,7 @@
       "name": "PowerStatsTestsRavenwood",
       "host": true,
       "options": [
-        {"include-filter": "com.android.server.power.stats"},
-        {"exclude-annotation": "android.platform.test.annotations.DisabledOnRavenwood"}
+        {"include-filter": "com.android.server.power.stats"}
       ]
     }
   ],
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 09f81f7..a862c43 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -678,3 +678,176 @@
     test_suites: ["device-tests"],
     include_filters: ["com.android.server.input"],
 }
+
+test_module_config {
+    name: "FrameworksServicesTests_server_job",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.job"],
+}
+
+test_module_config {
+    name: "FrameworksServicesTests_server_tare",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.tare"],
+}
+
+test_module_config {
+    name: "FrameworksServicesTests_server_usage",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.usage"],
+}
+
+test_module_config {
+    name: "FrameworksServicesTests_server_om",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.om"],
+}
+
+test_module_config {
+    name: "FrameworksServicesTests_server_accessibility",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.accessibility"],
+}
+
+test_module_config {
+    name: "FrameworksServicesTests_server_binarytransparencyservicetest",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.BinaryTransparencyServiceTest"],
+}
+
+test_module_config {
+    name: "FrameworksServicesTests_server_pinnerservicetest",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.PinnerServiceTest"],
+}
+
+test_module_config {
+    name: "FrameworksServicesTests_server_am",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.am."],
+}
+
+test_module_config {
+    name: "FrameworksServicesTests_server_hdmi",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.hdmi"],
+}
+
+test_module_config {
+    name: "FrameworksServicesTests_server_logcat",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.logcat"],
+}
+
+test_module_config {
+    name: "FrameworksServicesTests_server_net_Presubmit",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.net."],
+    include_annotations: ["android.platform.test.annotations.Presubmit"],
+}
+
+test_module_config {
+    name: "FrameworksServicesTests_server_policy_Presubmit",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.policy."],
+    include_annotations: ["android.platform.test.annotations.Presubmit"],
+}
+
+test_module_config {
+    name: "FrameworksServicesTests_server_policy",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.policy."],
+}
+
+test_module_config {
+    name: "FrameworksServicesTests_server_power",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.power"],
+}
+
+test_module_config {
+    name: "FrameworksServicesTests_power_hint",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.power.hint"],
+}
+
+test_module_config {
+    name: "FrameworksServicesTests_location_contexthub_Postsubmit",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.location.contexthub."],
+    include_annotations: ["android.platform.test.annotations.Postsubmit"],
+}
+
+test_module_config {
+    name: "FrameworksServicesTests_server_input",
+    base: "FrameworksServicesTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.input"],
+}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MouseKeysInterceptorTest.kt b/services/tests/servicestests/src/com/android/server/accessibility/MouseKeysInterceptorTest.kt
index 8753b25..019ccf9 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MouseKeysInterceptorTest.kt
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MouseKeysInterceptorTest.kt
@@ -48,6 +48,7 @@
 import java.util.LinkedList
 import java.util.Queue
 import android.util.ArraySet
+import android.view.InputDevice
 
 /**
  * Tests for {@link MouseKeysInterceptor}
@@ -68,6 +69,8 @@
     }
 
     private lateinit var mouseKeysInterceptor: MouseKeysInterceptor
+    private lateinit var inputDevice: InputDevice
+
     private val clock = OffsettableClock()
     private val testLooper = TestLooper { clock.now() }
     private val nextInterceptor = TrackingInterceptor()
@@ -98,6 +101,10 @@
         testSession = InputManagerGlobal.createTestSession(iInputManager)
         mockInputManager = InputManager(context)
 
+        inputDevice = createInputDevice(DEVICE_ID)
+        Mockito.`when`(iInputManager.getInputDevice(DEVICE_ID))
+                .thenReturn(inputDevice)
+
         Mockito.`when`(mockVirtualDeviceManagerInternal.getDeviceIdsForUid(Mockito.anyInt()))
             .thenReturn(ArraySet(setOf(DEVICE_ID)))
         LocalServices.removeServiceForTest(VirtualDeviceManagerInternal::class.java)
@@ -115,7 +122,8 @@
         Mockito.`when`(iInputManager.inputDeviceIds).thenReturn(intArrayOf(DEVICE_ID))
         Mockito.`when`(mockAms.traceManager).thenReturn(mockTraceManager)
 
-        mouseKeysInterceptor = MouseKeysInterceptor(mockAms, testLooper.looper, DISPLAY_ID)
+        mouseKeysInterceptor = MouseKeysInterceptor(mockAms, mockInputManager,
+                testLooper.looper, DISPLAY_ID)
         mouseKeysInterceptor.next = nextInterceptor
     }
 
@@ -281,6 +289,17 @@
         }
     }
 
+    private fun createInputDevice(
+            deviceId: Int,
+            generation: Int = -1
+    ): InputDevice =
+            InputDevice.Builder()
+                    .setId(deviceId)
+                    .setName("Device $deviceId")
+                    .setDescriptor("descriptor $deviceId")
+                    .setGeneration(generation)
+                    .build()
+
     private class TrackingInterceptor : BaseEventStreamTransformation() {
         val events: Queue<KeyEvent> = LinkedList()
 
diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
index 2a55521..a25621a 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -90,6 +90,7 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IRemoteCallback;
+import android.os.IpcDataCache;
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManagerInternal;
@@ -197,6 +198,9 @@
     @Before
     public void setUp() throws Exception {
         runWithDexmakerShareClassLoader(() -> {
+            // Disable binder caches in this process.
+            IpcDataCache.disableForTestMode();
+
             mInjector = spy(new TestInjector(getInstrumentation().getTargetContext()));
             doNothing().when(mInjector).clearAllLockedTasks(anyString());
             doNothing().when(mInjector).startHomeActivity(anyInt(), anyString());
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
index 4c3a233..760d38e 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
@@ -264,6 +264,22 @@
         assertThat(preAuthInfo.eligibleSensors).hasSize(0);
     }
 
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+    public void testMandatoryBiometricsNegativeButtonText_whenSet()
+            throws Exception {
+        when(mTrustManager.isInSignificantPlace()).thenReturn(false);
+
+        final BiometricSensor sensor = getFaceSensor();
+        final PromptInfo promptInfo = new PromptInfo();
+        promptInfo.setAuthenticators(BiometricManager.Authenticators.MANDATORY_BIOMETRICS);
+        promptInfo.setNegativeButtonText(TEST_PACKAGE_NAME);
+        final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
+                mSettingObserver, List.of(sensor), 0 /* userId */, promptInfo, TEST_PACKAGE_NAME,
+                false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager);
+        assertThat(promptInfo.getNegativeButtonText()).isEqualTo(TEST_PACKAGE_NAME);
+    }
+
     private BiometricSensor getFingerprintSensor() {
         BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FINGERPRINT,
                 TYPE_FINGERPRINT, BiometricManager.Authenticators.BIOMETRIC_STRONG,
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 7912156..e652df5 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -34,6 +34,7 @@
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.os.IpcDataCache;
 import android.os.PersistableBundle;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -100,6 +101,9 @@
 
     @Before
     public void setUp() throws Exception {
+        // Disable binder caches in this process.
+        IpcDataCache.disableForTestMode();
+
         mOriginalCurrentUserId = ActivityManager.getCurrentUser();
         mUserManager = UserManager.get(mContext);
         mActivityManager = mContext.getSystemService(ActivityManager.class);
diff --git a/services/tests/timetests/Android.bp b/services/tests/timetests/Android.bp
index 23ab859..05a1433 100644
--- a/services/tests/timetests/Android.bp
+++ b/services/tests/timetests/Android.bp
@@ -25,3 +25,27 @@
     certificate: "platform",
     test_suites: ["device-tests"],
 }
+
+test_module_config {
+    name: "FrameworksTimeServicesTests_time",
+    base: "FrameworksTimeServicesTests",
+    test_suites: ["device-tests"],
+    include_filters: [
+        "com.android.server.timezonedetector.",
+        "com.android.server.timedetector.",
+    ],
+}
+
+test_module_config {
+    name: "FrameworksTimeServicesTests_server_timedetector",
+    base: "FrameworksTimeServicesTests",
+    test_suites: ["device-tests"],
+    include_filters: ["com.android.server.timedetector."],
+}
+
+test_module_config {
+    name: "FrameworksTimeServicesTests_server_timezonedetector",
+    base: "FrameworksTimeServicesTests",
+    test_suites: ["device-tests"],
+    include_filters: ["com.android.server.timezonedetector."],
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java b/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java
index b3ec215..c9d5241 100644
--- a/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java
+++ b/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java
@@ -30,6 +30,7 @@
 
 import androidx.test.InstrumentationRegistry;
 
+import com.android.server.pm.UserManagerInternal;
 import com.android.server.uri.UriGrantsManagerInternal;
 
 import org.junit.After;
@@ -41,6 +42,7 @@
 
 public class UiServiceTestCase {
     @Mock protected PackageManagerInternal mPmi;
+    @Mock protected UserManagerInternal mUmi;
     @Mock protected UriGrantsManagerInternal mUgmInternal;
 
     protected static final String PKG_N_MR1 = "com.example.n_mr1";
@@ -92,6 +94,8 @@
                     }
                 });
 
+        LocalServices.removeServiceForTest(UserManagerInternal.class);
+        LocalServices.addService(UserManagerInternal.class, mUmi);
         LocalServices.removeServiceForTest(UriGrantsManagerInternal.class);
         LocalServices.addService(UriGrantsManagerInternal.class, mUgmInternal);
         when(mUgmInternal.checkGrantUriPermission(
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java b/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java
index 7933f7a..4a19973 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java
@@ -46,6 +46,7 @@
 import android.content.IntentFilter;
 import android.hardware.display.ColorDisplayManager;
 import android.os.PowerManager;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.service.notification.ZenDeviceEffects;
 import android.testing.TestableContext;
@@ -64,6 +65,9 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
 @RunWith(TestParameterInjector.class)
 public class DefaultDeviceEffectsApplierTest {
 
@@ -89,6 +93,8 @@
 
         mApplier = new DefaultDeviceEffectsApplier(mContext);
         verify(mWallpaperManager).isWallpaperSupported();
+
+        ZenLog.clear();
     }
 
     @Test
@@ -110,6 +116,41 @@
     }
 
     @Test
+    @EnableFlags(android.app.Flags.FLAG_MODES_API)
+    public void apply_logsToZenLog() {
+        when(mPowerManager.isInteractive()).thenReturn(true);
+        ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
+                ArgumentCaptor.forClass(BroadcastReceiver.class);
+        ArgumentCaptor<IntentFilter> intentFilterCaptor =
+                ArgumentCaptor.forClass(IntentFilter.class);
+
+        ZenDeviceEffects effects = new ZenDeviceEffects.Builder()
+                .setShouldDisplayGrayscale(true)
+                .setShouldUseNightMode(true)
+                .build();
+        mApplier.apply(effects, ORIGIN_APP);
+
+        String zenLog = getZenLog();
+        assertThat(zenLog).contains("apply_device_effect: displayGrayscale -> true");
+        assertThat(zenLog).contains("schedule_device_effect: nightMode -> true");
+        assertThat(zenLog).doesNotContain("apply_device_effect: nightMode");
+
+        verify(mContext).registerReceiver(broadcastReceiverCaptor.capture(),
+                intentFilterCaptor.capture(), anyInt());
+        BroadcastReceiver screenOffReceiver = broadcastReceiverCaptor.getValue();
+        screenOffReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF));
+
+        zenLog = getZenLog();
+        assertThat(zenLog).contains("apply_device_effect: nightMode -> true");
+    }
+
+    private static String getZenLog() {
+        StringWriter zenLogWriter = new StringWriter();
+        ZenLog.dump(new PrintWriter(zenLogWriter), "");
+        return zenLogWriter.toString();
+    }
+
+    @Test
     public void apply_removesEffects() {
         mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API);
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
index fb82b872c..4e376aa 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
@@ -1542,6 +1542,7 @@
         assertTrue(componentsToUnbind.get(0).contains(ComponentName.unflattenFromString("c/c")));
     }
 
+    @SuppressWarnings("GuardedBy")
     @Test
     public void populateComponentsToBind() {
         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
@@ -1565,7 +1566,8 @@
 
         SparseArray<Set<ComponentName>> componentsToBind = new SparseArray<>();
 
-        service.populateComponentsToBind(componentsToBind, users, approvedComponentsByUser);
+        service.populateComponentsToBind(componentsToBind, users, approvedComponentsByUser,
+                /* isVisibleBackgroundUser= */ false);
 
         assertEquals(2, componentsToBind.size());
         assertEquals(1, componentsToBind.get(0).size());
@@ -1575,6 +1577,33 @@
         assertTrue(componentsToBind.get(10).contains(ComponentName.unflattenFromString("c/c")));
     }
 
+    @SuppressWarnings("GuardedBy")
+    @Test
+    public void populateComponentsToBind_isVisibleBackgroundUser_addComponentsToBindButNotAddToEnabledComponent() {
+        ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
+                APPROVAL_BY_COMPONENT);
+
+        SparseArray<ArraySet<ComponentName>> approvedComponentsByUser = new SparseArray<>();
+        ArraySet<ComponentName> allowed = new ArraySet<>();
+        allowed.add(ComponentName.unflattenFromString("pkg1/cmp1"));
+        approvedComponentsByUser.put(11, allowed);
+        IntArray users = new IntArray();
+        users.add(11);
+
+        SparseArray<Set<ComponentName>> componentsToBind = new SparseArray<>();
+
+        service.populateComponentsToBind(componentsToBind, users, approvedComponentsByUser,
+                /* isVisibleBackgroundUser= */ true);
+
+        assertEquals(1, componentsToBind.size());
+        assertEquals(1, componentsToBind.get(11).size());
+        assertTrue(componentsToBind.get(11).contains(ComponentName.unflattenFromString(
+                "pkg1/cmp1")));
+        assertThat(service.isComponentEnabledForCurrentProfiles(
+                new ComponentName("pkg1", "cmp1"))).isFalse();
+        assertThat(service.isComponentEnabledForPackage("pkg1")).isFalse();
+    }
+
     @Test
     public void testOnNullBinding() throws Exception {
         Context context = mock(Context.class);
diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp
index 604869c..289f8a9 100644
--- a/services/tests/wmtests/Android.bp
+++ b/services/tests/wmtests/Android.bp
@@ -109,3 +109,35 @@
         ":OverlayTestApp",
     ],
 }
+
+test_module_config {
+    name: "WmTests_server_policy_Presubmit",
+    base: "WmTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.policy."],
+    include_annotations: ["android.platform.test.annotations.Presubmit"],
+}
+
+test_module_config {
+    name: "WmTests_server_policy",
+    base: "WmTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.policy."],
+}
+
+test_module_config {
+    name: "WmTests_wm_utils_Presubmit",
+    base: "WmTests",
+    test_suites: [
+        "automotive-tests",
+        "device-tests",
+    ],
+    include_filters: ["com.android.server.wm.utils"],
+    include_annotations: ["android.platform.test.annotations.Presubmit"],
+}
diff --git a/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java
index 07934ea..e694c0b 100644
--- a/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java
@@ -188,7 +188,7 @@
                 .FLAG_CREATE_ACCESSIBILITY_OVERLAY_APP_OP_ENABLED);
         int[] outAppOp = new int[1];
         assertEquals(ADD_OKAY, mPhoneWindowManager.checkAddPermission(TYPE_WALLPAPER,
-                /* isRoundedCornerOverlay= */ false, "test.pkg", outAppOp));
+                /* isRoundedCornerOverlay= */ false, "test.pkg", outAppOp, DEFAULT_DISPLAY));
         assertThat(outAppOp[0]).isEqualTo(AppOpsManager.OP_NONE);
     }
 
@@ -198,7 +198,7 @@
                 .FLAG_CREATE_ACCESSIBILITY_OVERLAY_APP_OP_ENABLED);
         int[] outAppOp = new int[1];
         assertEquals(ADD_OKAY, mPhoneWindowManager.checkAddPermission(TYPE_ACCESSIBILITY_OVERLAY,
-                /* isRoundedCornerOverlay= */ false, "test.pkg", outAppOp));
+                /* isRoundedCornerOverlay= */ false, "test.pkg", outAppOp, DEFAULT_DISPLAY));
         assertThat(outAppOp[0]).isEqualTo(AppOpsManager.OP_CREATE_ACCESSIBILITY_OVERLAY);
     }
 
@@ -208,7 +208,7 @@
                 .FLAG_CREATE_ACCESSIBILITY_OVERLAY_APP_OP_ENABLED);
         int[] outAppOp = new int[1];
         assertEquals(ADD_OKAY, mPhoneWindowManager.checkAddPermission(TYPE_ACCESSIBILITY_OVERLAY,
-                /* isRoundedCornerOverlay= */ false, "test.pkg", outAppOp));
+                /* isRoundedCornerOverlay= */ false, "test.pkg", outAppOp, DEFAULT_DISPLAY));
         assertThat(outAppOp[0]).isEqualTo(AppOpsManager.OP_NONE);
     }
 
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 4f94704..c706d52 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -1047,6 +1047,7 @@
         info.packageName = packageName;
         WindowProcessController wpc = new WindowProcessController(
                 mAtm, info, packageName, 0, userId, null, mMockListener);
+        mAtm.mInternal.preBindApplication(wpc, info);
         wpc.setThread(mock(IApplicationThread.class));
         return wpc;
     }
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 44837d7..20dcdde 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -110,6 +110,7 @@
         mWindowManagerInternal = mock(WindowManagerInternal.class);
         LocalServices.addService(WindowManagerInternal.class, mWindowManagerInternal);
         mBackAnimationAdapter = mock(BackAnimationAdapter.class);
+        doReturn(true).when(mBackAnimationAdapter).isAnimatable(anyInt());
         mNavigationMonitor = mock(BackNavigationController.NavigationMonitor.class);
         mRootHomeTask = initHomeActivity();
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
index 57839e2..ffe3893 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
@@ -244,6 +244,19 @@
         mWm.clearForcedDisplaySize(mSecondaryDisplay.getDisplayId());
         assertEquals(mSecondaryDisplay.mInitialDisplayWidth, mSecondaryDisplay.mBaseDisplayWidth);
         assertEquals(mSecondaryDisplay.mInitialDisplayHeight, mSecondaryDisplay.mBaseDisplayHeight);
+
+        // Forced size can be cleared even if the initial display size is smaller than max width.
+        final int maxWidth = mSecondaryDisplay.mInitialDisplayWidth - 20;
+        mSecondaryDisplay.setMaxUiWidth(maxWidth);
+        assertEquals(maxWidth, mSecondaryDisplay.mBaseDisplayWidth);
+        mSecondaryDisplay.setForcedSize(maxWidth - 10, maxWidth + 10);
+        assertNotEquals(maxWidth, mSecondaryDisplay.mBaseDisplayHeight);
+        assertTrue(mSecondaryDisplay.mIsSizeForced);
+
+        mWm.clearForcedDisplaySize(mSecondaryDisplay.mDisplayId);
+        assertFalse(mSecondaryDisplay.mIsSizeForced);
+        assertEquals(maxWidth, mSecondaryDisplay.mBaseDisplayWidth);
+        assertEquals(0, mSettingsProvider.getSettings(originalInfo).mForcedWidth);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index d62c626..eebb487 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -60,7 +60,7 @@
 
     @Override
     public int checkAddPermission(int type, boolean isRoundedCornerOverlay, String packageName,
-            int[] outAppOp) {
+            int[] outAppOp, int displayId) {
         return 0;
     }
 
diff --git a/telephony/common/android/telephony/LocationAccessPolicy.java b/telephony/common/android/telephony/LocationAccessPolicy.java
index feea55b..a678147 100644
--- a/telephony/common/android/telephony/LocationAccessPolicy.java
+++ b/telephony/common/android/telephony/LocationAccessPolicy.java
@@ -33,7 +33,6 @@
 import android.widget.Toast;
 
 import com.android.internal.telephony.TelephonyPermissions;
-import com.android.internal.telephony.flags.Flags;
 import com.android.internal.telephony.util.TelephonyUtils;
 
 /**
@@ -312,18 +311,10 @@
         // This avoid breaking legacy code that rely on public-facing APIs to access cell location,
         // and it doesn't create an info leak risk because the cell location is stored in the phone
         // process anyway, and the system server already has location access.
-        if (Flags.supportPhoneUidCheckForMultiuser()) {
-            if (TelephonyPermissions.isSystemOrPhone(query.callingUid)
-                    || UserHandle.isSameApp(query.callingUid, Process.NETWORK_STACK_UID)
-                    || UserHandle.isSameApp(query.callingUid, Process.ROOT_UID)) {
-                return LocationPermissionResult.ALLOWED;
-            }
-        } else {
-            if (query.callingUid == Process.PHONE_UID || query.callingUid == Process.SYSTEM_UID
-                    || query.callingUid == Process.NETWORK_STACK_UID
-                    || query.callingUid == Process.ROOT_UID) {
-                return LocationPermissionResult.ALLOWED;
-            }
+        if (TelephonyPermissions.isSystemOrPhone(query.callingUid)
+                || UserHandle.isSameApp(query.callingUid, Process.NETWORK_STACK_UID)
+                || UserHandle.isSameApp(query.callingUid, Process.ROOT_UID)) {
+            return LocationPermissionResult.ALLOWED;
         }
 
         // Check the system-wide requirements. If the location main switch is off and the caller is
diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
index 7ed26fb..b80610a 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -35,7 +35,6 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.flags.Flags;
 
 import java.util.HashMap;
 import java.util.HashSet;
@@ -934,12 +933,8 @@
      * as system user or not.
      */
     public static boolean isSystemOrPhone(int uid) {
-        if (Flags.supportPhoneUidCheckForMultiuser()) {
-            return UserHandle.isSameApp(uid, Process.SYSTEM_UID) || UserHandle.isSameApp(uid,
-                    Process.PHONE_UID);
-        } else {
-            return uid == Process.SYSTEM_UID || uid == Process.PHONE_UID;
-        }
+        return UserHandle.isSameApp(uid, Process.SYSTEM_UID) || UserHandle.isSameApp(uid,
+                Process.PHONE_UID);
     }
 
     /**
@@ -947,11 +942,7 @@
      * as system user or not.
      */
     public static boolean isRootOrShell(int uid) {
-        if (Flags.supportPhoneUidCheckForMultiuser()) {
-            return UserHandle.isSameApp(uid, Process.ROOT_UID) || UserHandle.isSameApp(uid,
-                    Process.SHELL_UID);
-        } else {
-            return uid == Process.ROOT_UID || uid == Process.SHELL_UID;
-        }
+        return UserHandle.isSameApp(uid, Process.ROOT_UID) || UserHandle.isSameApp(uid,
+                Process.SHELL_UID);
     }
 }
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 13bd5eb..aca0941 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -10098,8 +10098,8 @@
      * The default value is 30 seconds.
      */
     @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
-    public static final String KEY_SATELLITE_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT =
-            "satellite_screen_off_inactivity_timeout_sec_int";
+    public static final String KEY_SATELLITE_ROAMING_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT =
+            "satellite_roaming_screen_off_inactivity_timeout_sec_int";
 
     /**
      * An integer key holds the timeout duration in seconds used to determine whether to exit P2P
@@ -10112,8 +10112,8 @@
      * The default value is 180 seconds.
      */
     @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
-    public static final String KEY_SATELLITE_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT =
-            "satellite_p2p_sms_inactivity_timeout_sec_int";
+    public static final String KEY_SATELLITE_ROAMING_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT =
+            "satellite_roaming_p2p_sms_inactivity_timeout_sec_int";
 
     /**
      * An integer key holds the timeout duration in seconds used to determine whether to exit ESOS
@@ -10126,8 +10126,8 @@
      * The default value is 600 seconds.
      */
     @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
-    public static final String KEY_SATELLITE_ESOS_INACTIVITY_TIMEOUT_SEC_INT =
-            "satellite_esos_inactivity_timeout_sec_int";
+    public static final String KEY_SATELLITE_ROAMING_ESOS_INACTIVITY_TIMEOUT_SEC_INT =
+            "satellite_roaming_esos_inactivity_timeout_sec_int";
 
     /**
      * Indicating whether DUN APN should be disabled when the device is roaming. In that case,
@@ -11294,9 +11294,9 @@
         sDefaults.putInt(KEY_CARRIER_ROAMING_NTN_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_INT,
                 SatelliteManager.EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911);
         sDefaults.putInt(KEY_CARRIER_SUPPORTED_SATELLITE_NOTIFICATION_HYSTERESIS_SEC_INT, 180);
-        sDefaults.putInt(KEY_SATELLITE_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT, 30);
-        sDefaults.putInt(KEY_SATELLITE_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT, 180);
-        sDefaults.putInt(KEY_SATELLITE_ESOS_INACTIVITY_TIMEOUT_SEC_INT, 600);
+        sDefaults.putInt(KEY_SATELLITE_ROAMING_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT, 30);
+        sDefaults.putInt(KEY_SATELLITE_ROAMING_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT, 180);
+        sDefaults.putInt(KEY_SATELLITE_ROAMING_ESOS_INACTIVITY_TIMEOUT_SEC_INT, 600);
         sDefaults.putString(KEY_DEFAULT_PREFERRED_APN_NAME_STRING, "");
         sDefaults.putBoolean(KEY_SUPPORTS_CALL_COMPOSER_BOOL, false);
         sDefaults.putBoolean(KEY_SUPPORTS_BUSINESS_CALL_COMPOSER_BOOL, false);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index bc709ab..3ff1e2c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -23,6 +23,7 @@
 import static com.android.internal.util.Preconditions.checkNotNull;
 
 import android.Manifest;
+import android.annotation.BoolRes;
 import android.annotation.BytesLong;
 import android.annotation.CallbackExecutor;
 import android.annotation.CurrentTimeMillisLong;
@@ -6886,6 +6887,26 @@
         }
     }
 
+    // Suppressing AndroidFrameworkCompatChange because we're querying vendor
+    // partition SDK level, not application's target SDK version.
+    @SuppressWarnings("AndroidFrameworkCompatChange")
+    private boolean hasCapability(@NonNull String feature, @BoolRes int legacySetting) {
+        if (mContext == null) return true;
+
+        if (mContext.getPackageManager().hasSystemFeature(feature)) return true;
+
+        // Check SDK version of the vendor partition.
+        final int vendorApiLevel = SystemProperties.getInt(
+                "ro.vendor.api_level", Build.VERSION.DEVICE_INITIAL_SDK_INT);
+        // Devices shipped with 2024Q2 or later are required to declare FEATURE_TELEPHONY_*
+        // for individual sub-features (calling, messaging, data), so there's no need to check
+        // the legacy setting.
+        if (vendorApiLevel < Build.VENDOR_API_2024_Q2) {
+            return mContext.getResources().getBoolean(legacySetting);
+        }
+        return false;
+    }
+
     // TODO(b/316183370): replace all @code with @link in javadoc after feature is released
     /**
      * @return true if the current device is "voice capable".
@@ -6905,11 +6926,9 @@
      * device (when {@code #isDeviceVoiceCapable} return {@code true}), caller should check for
      * subscription-level voice capability as well. See {@code #isDeviceVoiceCapable} for details.
      */
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     @Deprecated
     public boolean isVoiceCapable() {
-        if (mContext == null) return true;
-        return mContext.getResources().getBoolean(
+        return hasCapability(PackageManager.FEATURE_TELEPHONY_CALLING,
                 com.android.internal.R.bool.config_voice_capable);
     }
 
@@ -6932,7 +6951,6 @@
      *
      * @see SubscriptionInfo#getServiceCapabilities()
      */
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     @FlaggedApi(Flags.FLAG_DATA_ONLY_CELLULAR_SERVICE)
     public boolean isDeviceVoiceCapable() {
         return isVoiceCapable();
@@ -6951,10 +6969,9 @@
      * device (when {@code #isDeviceSmsCapable} return {@code true}), caller should check for
      * subscription-level SMS capability as well. See {@code #isDeviceSmsCapable} for details.
      */
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)
+    @Deprecated
     public boolean isSmsCapable() {
-        if (mContext == null) return true;
-        return mContext.getResources().getBoolean(
+        return hasCapability(PackageManager.FEATURE_TELEPHONY_MESSAGING,
                 com.android.internal.R.bool.config_sms_capable);
     }
 
@@ -6974,7 +6991,6 @@
      *
      * @see SubscriptionInfo#getServiceCapabilities()
      */
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)
     @FlaggedApi(Flags.FLAG_DATA_ONLY_CELLULAR_SERVICE)
     public boolean isDeviceSmsCapable() {
         return isSmsCapable();
@@ -14542,10 +14558,8 @@
      * data connections over the telephony network.
      * <p>
      */
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public boolean isDataCapable() {
-        if (mContext == null) return true;
-        return mContext.getResources().getBoolean(
+        return hasCapability(PackageManager.FEATURE_TELEPHONY_DATA,
                 com.android.internal.R.bool.config_mobile_data_capable);
     }
 
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index 83fc0dc..3944b8e 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -412,6 +412,14 @@
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_EMERGENCY_CALL_IN_PROGRESS = 27;
 
+    /**
+     * Disabling satellite is in progress.
+     *
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+    public static final int SATELLITE_RESULT_DISABLE_IN_PROGRESS = 28;
+
     /** @hide */
     @IntDef(prefix = {"SATELLITE_RESULT_"}, value = {
             SATELLITE_RESULT_SUCCESS,
@@ -441,7 +449,8 @@
             SATELLITE_RESULT_MODEM_TIMEOUT,
             SATELLITE_RESULT_LOCATION_DISABLED,
             SATELLITE_RESULT_LOCATION_NOT_AVAILABLE,
-            SATELLITE_RESULT_EMERGENCY_CALL_IN_PROGRESS
+            SATELLITE_RESULT_EMERGENCY_CALL_IN_PROGRESS,
+            SATELLITE_RESULT_DISABLE_IN_PROGRESS
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface SatelliteResult {}
diff --git a/telephony/java/android/telephony/satellite/stub/ISatellite.aidl b/telephony/java/android/telephony/satellite/stub/ISatellite.aidl
index 51154e5..8b51321 100644
--- a/telephony/java/android/telephony/satellite/stub/ISatellite.aidl
+++ b/telephony/java/android/telephony/satellite/stub/ISatellite.aidl
@@ -83,7 +83,16 @@
      * is enabled, this may also disable the cellular modem, and if the satellite modem is disabled,
      * this may also re-enable the cellular modem.
      *
+     * Framework might send an enable request to update the enable attributes of an already-started
+     * satellite session. In such cases, modem needs to apply the new enable attrbitues to the
+     * satellite session. Moreover, modem needs to report its current state and signal strength
+     * level to framework right after receiving this request from framework.
+     *
+     * Framework might send a disable request when an enable request is being processed. In such
+     * cases, modem needs to abort the enable request and process the disable request.
+     *
      * @param enableAttributes The enable parameters that will be applied to the satellite session
+     * @param resultCallback The callback to receive the error code result of the operation.
      *
      * Valid result codes returned:
      *   SatelliteResult:SATELLITE_RESULT_SUCCESS
diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
index 29286e8..b92ba66 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
@@ -169,13 +169,13 @@
 
     /**
      * Set to false to disable SMS receiving, default is
-     * the value of config_sms_capable
+     * the value of TelephonyManager.isDeviceSmsCapable
      */
     static final String PROPERTY_SMS_RECEIVE = "telephony.sms.receive";
 
     /**
      * Set to false to disable SMS sending, default is
-     * the value of config_sms_capable
+     * the value of TelephonyManager.isDeviceSmsCapable
      */
     static final String PROPERTY_SMS_SEND = "telephony.sms.send";
 
diff --git a/tests/Input/src/com/android/server/input/debug/TouchpadDebugViewControllerTests.java b/tests/Input/src/com/android/server/input/debug/TouchpadDebugViewControllerTests.java
new file mode 100644
index 0000000..c7ebd3a
--- /dev/null
+++ b/tests/Input/src/com/android/server/input/debug/TouchpadDebugViewControllerTests.java
@@ -0,0 +1,215 @@
+/*
+ * 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.server.input.debug;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.hardware.input.InputManager;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableContext;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.InputDevice;
+import android.view.WindowInsets;
+import android.view.WindowManager;
+import android.view.WindowMetrics;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.server.input.InputManagerService;
+
+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;
+
+/**
+ * Build/Install/Run:
+ * atest TouchpadDebugViewControllerTests
+ */
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class TouchpadDebugViewControllerTests {
+    private static final int DEVICE_ID = 1000;
+    private static final String TAG = "TouchpadDebugViewController";
+
+    @Rule
+    public final MockitoRule mockito = MockitoJUnit.rule();
+
+    private Context mContext;
+    private TouchpadDebugViewController mTouchpadDebugViewController;
+    @Mock
+    private InputManager mInputManagerMock;
+    @Mock
+    private InputManagerService mInputManagerServiceMock;
+    @Mock
+    private WindowManager mWindowManagerMock;
+    private TestableLooper mTestableLooper;
+
+    @Before
+    public void setup() throws Exception {
+        mContext = InstrumentationRegistry.getInstrumentation().getContext();
+        TestableContext mTestableContext = new TestableContext(mContext);
+        mTestableContext.addMockSystemService(WindowManager.class, mWindowManagerMock);
+
+        Rect bounds = new Rect(0, 0, 2560, 1600);
+        WindowMetrics metrics = new WindowMetrics(bounds, new WindowInsets(bounds), 1.0f);
+
+        when(mWindowManagerMock.getCurrentWindowMetrics()).thenReturn(metrics);
+
+        unMockTouchpad();
+
+        mTestableLooper = TestableLooper.get(this);
+
+        mTestableContext.addMockSystemService(InputManager.class, mInputManagerMock);
+
+        mTouchpadDebugViewController = new TouchpadDebugViewController(mTestableContext,
+                mTestableLooper.getLooper(), mInputManagerServiceMock);
+    }
+
+    private InputDevice createTouchpadInputDevice(int id) {
+        return new InputDevice.Builder()
+                .setId(id)
+                .setSources(InputDevice.SOURCE_TOUCHPAD | InputDevice.SOURCE_MOUSE)
+                .setName("Test Device " + id)
+                .build();
+    }
+
+    private void mockTouchpad() {
+        when(mInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{DEVICE_ID});
+        when(mInputManagerMock.getInputDevice(eq(DEVICE_ID))).thenReturn(
+                createTouchpadInputDevice(DEVICE_ID));
+    }
+
+    private void unMockTouchpad() {
+        when(mInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{});
+        when(mInputManagerMock.getInputDevice(eq(DEVICE_ID))).thenReturn(null);
+    }
+
+    @Test
+    public void touchpadConnectedWhileSettingDisabled() throws Exception {
+        mTouchpadDebugViewController.updateTouchpadVisualizerEnabled(false);
+
+        mockTouchpad();
+        mTouchpadDebugViewController.onInputDeviceAdded(DEVICE_ID);
+
+        verify(mWindowManagerMock, never()).addView(any(), any());
+        verify(mWindowManagerMock, never()).removeView(any());
+    }
+
+    @Test
+    public void settingEnabledWhileNoTouchpadConnected() throws Exception {
+        mTouchpadDebugViewController.updateTouchpadVisualizerEnabled(true);
+
+        verify(mWindowManagerMock, never()).addView(any(), any());
+        verify(mWindowManagerMock, never()).removeView(any());
+    }
+
+    @Test
+    public void touchpadConnectedWhileSettingEnabled() throws Exception {
+        mTouchpadDebugViewController.updateTouchpadVisualizerEnabled(true);
+
+        mockTouchpad();
+        mTouchpadDebugViewController.onInputDeviceAdded(DEVICE_ID);
+
+        verify(mWindowManagerMock, times(1)).addView(any(), any());
+        verify(mWindowManagerMock, never()).removeView(any());
+    }
+
+    @Test
+    public void touchpadConnectedWhileSettingEnabledThenDisabled() throws Exception {
+        mTouchpadDebugViewController.updateTouchpadVisualizerEnabled(true);
+
+        mockTouchpad();
+        mTouchpadDebugViewController.onInputDeviceAdded(DEVICE_ID);
+
+        verify(mWindowManagerMock, times(1)).addView(any(), any());
+        verify(mWindowManagerMock, never()).removeView(any());
+
+        mTouchpadDebugViewController.updateTouchpadVisualizerEnabled(false);
+
+        verify(mWindowManagerMock, times(1)).addView(any(), any());
+        verify(mWindowManagerMock, times(1)).removeView(any());
+    }
+
+    @Test
+    public void touchpadConnectedWhileSettingDisabledThenEnabled() throws Exception {
+        mTouchpadDebugViewController.updateTouchpadVisualizerEnabled(false);
+
+        mockTouchpad();
+        mTouchpadDebugViewController.onInputDeviceAdded(DEVICE_ID);
+
+        verify(mWindowManagerMock, never()).addView(any(), any());
+        verify(mWindowManagerMock, never()).removeView(any());
+
+        mTouchpadDebugViewController.updateTouchpadVisualizerEnabled(true);
+
+        verify(mWindowManagerMock, times(1)).addView(any(), any());
+        verify(mWindowManagerMock, never()).removeView(any());
+    }
+
+    @Test
+    public void touchpadConnectedWhileSettingDisabledThenTouchpadDisconnected() throws Exception {
+        mTouchpadDebugViewController.updateTouchpadVisualizerEnabled(false);
+
+        mockTouchpad();
+        mTouchpadDebugViewController.onInputDeviceAdded(DEVICE_ID);
+
+        verify(mWindowManagerMock, never()).addView(any(), any());
+        verify(mWindowManagerMock, never()).removeView(any());
+
+        unMockTouchpad();
+        mTouchpadDebugViewController.onInputDeviceRemoved(DEVICE_ID);
+
+        verify(mWindowManagerMock, never()).addView(any(), any());
+        verify(mWindowManagerMock, never()).removeView(any());
+    }
+
+    @Test
+    public void touchpadConnectedWhileSettingEnabledThenTouchpadDisconnectedThenSettingDisabled()
+            throws Exception {
+        mTouchpadDebugViewController.updateTouchpadVisualizerEnabled(true);
+
+        mockTouchpad();
+        mTouchpadDebugViewController.onInputDeviceAdded(DEVICE_ID);
+
+        verify(mWindowManagerMock, times(1)).addView(any(), any());
+        verify(mWindowManagerMock, never()).removeView(any());
+
+        unMockTouchpad();
+        mTouchpadDebugViewController.onInputDeviceRemoved(DEVICE_ID);
+
+        verify(mWindowManagerMock, times(1)).addView(any(), any());
+        verify(mWindowManagerMock, times(1)).removeView(any());
+
+        mTouchpadDebugViewController.updateTouchpadVisualizerEnabled(false);
+
+        verify(mWindowManagerMock, times(1)).addView(any(), any());
+        verify(mWindowManagerMock, times(1)).removeView(any());
+    }
+}
diff --git a/tests/Input/src/com/android/server/input/debug/TouchpadDebugViewTest.java b/tests/Input/src/com/android/server/input/debug/TouchpadDebugViewTest.java
new file mode 100644
index 0000000..ad0ef1b
--- /dev/null
+++ b/tests/Input/src/com/android/server/input/debug/TouchpadDebugViewTest.java
@@ -0,0 +1,292 @@
+/*
+ * 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.server.input.debug;
+
+import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.testing.TestableContext;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.WindowInsets;
+import android.view.WindowManager;
+import android.view.WindowMetrics;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.cts.input.MotionEventBuilder;
+import com.android.cts.input.PointerBuilder;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Build/Install/Run:
+ * atest TouchpadDebugViewTest
+ */
+@RunWith(AndroidJUnit4.class)
+public class TouchpadDebugViewTest {
+    private static final int TOUCHPAD_DEVICE_ID = 6;
+
+    private TouchpadDebugView mTouchpadDebugView;
+    private WindowManager.LayoutParams mWindowLayoutParams;
+
+    @Mock
+    WindowManager mWindowManager;
+
+    Rect mWindowBounds;
+    WindowMetrics mWindowMetrics;
+    TestableContext mTestableContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        mTestableContext = new TestableContext(context);
+
+        mTestableContext.addMockSystemService(WindowManager.class, mWindowManager);
+
+        mWindowBounds = new Rect(0, 0, 2560, 1600);
+        mWindowMetrics = new WindowMetrics(mWindowBounds, new WindowInsets(mWindowBounds), 1.0f);
+
+        when(mWindowManager.getCurrentWindowMetrics()).thenReturn(mWindowMetrics);
+
+        mTouchpadDebugView = new TouchpadDebugView(mTestableContext, TOUCHPAD_DEVICE_ID);
+
+        mTouchpadDebugView.measure(
+                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
+                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
+        );
+
+        doAnswer(invocation -> {
+            mTouchpadDebugView.layout(0, 0, mTouchpadDebugView.getMeasuredWidth(),
+                    mTouchpadDebugView.getMeasuredHeight());
+            return null;
+        }).when(mWindowManager).addView(any(), any());
+
+        doAnswer(invocation -> {
+            mTouchpadDebugView.layout(0, 0, mTouchpadDebugView.getMeasuredWidth(),
+                    mTouchpadDebugView.getMeasuredHeight());
+            return null;
+        }).when(mWindowManager).updateViewLayout(any(), any());
+
+        mWindowLayoutParams = mTouchpadDebugView.getWindowLayoutParams();
+        mWindowLayoutParams.x = 20;
+        mWindowLayoutParams.y = 20;
+
+        mTouchpadDebugView.layout(0, 0, mTouchpadDebugView.getMeasuredWidth(),
+                mTouchpadDebugView.getMeasuredHeight());
+    }
+
+    @Test
+    public void testDragView() {
+        // Initial view position relative to screen.
+        int initialX = mWindowLayoutParams.x;
+        int initialY = mWindowLayoutParams.y;
+
+        float offsetX = ViewConfiguration.get(mTestableContext).getScaledTouchSlop() + 10;
+        float offsetY = ViewConfiguration.get(mTestableContext).getScaledTouchSlop() + 10;
+
+        // Simulate ACTION_DOWN event (initial touch).
+        MotionEvent actionDown = new MotionEventBuilder(MotionEvent.ACTION_DOWN, SOURCE_TOUCHSCREEN)
+                .pointer(new PointerBuilder(0, MotionEvent.TOOL_TYPE_FINGER)
+                        .x(40f)
+                        .y(40f)
+                )
+                .build();
+        mTouchpadDebugView.dispatchTouchEvent(actionDown);
+
+        verify(mWindowManager, times(0)).updateViewLayout(any(), any());
+
+        // Simulate ACTION_MOVE event (dragging to the right).
+        MotionEvent actionMove = new MotionEventBuilder(MotionEvent.ACTION_MOVE, SOURCE_TOUCHSCREEN)
+                .pointer(new PointerBuilder(0, MotionEvent.TOOL_TYPE_FINGER)
+                        .x(40f + offsetX)
+                        .y(40f + offsetY)
+                )
+                .build();
+        mTouchpadDebugView.dispatchTouchEvent(actionMove);
+
+        ArgumentCaptor<WindowManager.LayoutParams> mWindowLayoutParamsCaptor =
+                ArgumentCaptor.forClass(WindowManager.LayoutParams.class);
+        verify(mWindowManager).updateViewLayout(any(), mWindowLayoutParamsCaptor.capture());
+
+        // Verify position after ACTION_MOVE
+        assertEquals(initialX + (long) offsetX, mWindowLayoutParamsCaptor.getValue().x);
+        assertEquals(initialY + (long) offsetY, mWindowLayoutParamsCaptor.getValue().y);
+
+        // Simulate ACTION_UP event (release touch).
+        MotionEvent actionUp = new MotionEventBuilder(MotionEvent.ACTION_UP, SOURCE_TOUCHSCREEN)
+                .pointer(new PointerBuilder(0, MotionEvent.TOOL_TYPE_FINGER)
+                        .x(40f + offsetX)
+                        .y(40f + offsetY)
+                )
+                .build();
+        mTouchpadDebugView.dispatchTouchEvent(actionUp);
+
+        assertEquals(initialX + (long) offsetX, mWindowLayoutParamsCaptor.getValue().x);
+        assertEquals(initialY + (long) offsetY, mWindowLayoutParamsCaptor.getValue().y);
+    }
+
+    @Test
+    public void testDragViewOutOfBounds() {
+        int initialX = mWindowLayoutParams.x;
+        int initialY = mWindowLayoutParams.y;
+
+        MotionEvent actionDown = new MotionEventBuilder(MotionEvent.ACTION_DOWN, SOURCE_TOUCHSCREEN)
+                .pointer(new PointerBuilder(0, MotionEvent.TOOL_TYPE_FINGER)
+                        .x(initialX + 10f)
+                        .y(initialY + 10f)
+                )
+                .build();
+        mTouchpadDebugView.dispatchTouchEvent(actionDown);
+
+        verify(mWindowManager, times(0)).updateViewLayout(any(), any());
+
+        // Simulate ACTION_MOVE event (dragging far to the right and bottom, beyond screen bounds)
+        MotionEvent actionMove = new MotionEventBuilder(MotionEvent.ACTION_MOVE, SOURCE_TOUCHSCREEN)
+                .pointer(new PointerBuilder(0, MotionEvent.TOOL_TYPE_FINGER)
+                        .x(mWindowBounds.width() + mTouchpadDebugView.getWidth())
+                        .y(mWindowBounds.height() + mTouchpadDebugView.getHeight())
+                )
+                .build();
+        mTouchpadDebugView.dispatchTouchEvent(actionMove);
+
+        ArgumentCaptor<WindowManager.LayoutParams> mWindowLayoutParamsCaptor =
+                ArgumentCaptor.forClass(WindowManager.LayoutParams.class);
+        verify(mWindowManager).updateViewLayout(any(), mWindowLayoutParamsCaptor.capture());
+
+        // Verify the view has been clamped to the right and bottom edges of the screen
+        assertEquals(mWindowBounds.width() - mTouchpadDebugView.getWidth(),
+                mWindowLayoutParamsCaptor.getValue().x);
+        assertEquals(mWindowBounds.height() - mTouchpadDebugView.getHeight(),
+                mWindowLayoutParamsCaptor.getValue().y);
+
+        MotionEvent actionUp = new MotionEventBuilder(MotionEvent.ACTION_UP, SOURCE_TOUCHSCREEN)
+                .pointer(new PointerBuilder(0, MotionEvent.TOOL_TYPE_FINGER)
+                        .x(mWindowBounds.width() + mTouchpadDebugView.getWidth())
+                        .y(mWindowBounds.height() + mTouchpadDebugView.getHeight())
+                )
+                .build();
+        mTouchpadDebugView.dispatchTouchEvent(actionUp);
+
+        // Verify the view has been clamped to the right and bottom edges of the screen
+        assertEquals(mWindowBounds.width() - mTouchpadDebugView.getWidth(),
+                mWindowLayoutParamsCaptor.getValue().x);
+        assertEquals(mWindowBounds.height() - mTouchpadDebugView.getHeight(),
+                mWindowLayoutParamsCaptor.getValue().y);
+    }
+
+    @Test
+    public void testSlopOffset() {
+        int initialX = mWindowLayoutParams.x;
+        int initialY = mWindowLayoutParams.y;
+
+        float offsetX = ViewConfiguration.get(mTestableContext).getScaledTouchSlop() / 2.0f;
+        float offsetY = -(ViewConfiguration.get(mTestableContext).getScaledTouchSlop() / 2.0f);
+
+        MotionEvent actionDown = new MotionEventBuilder(MotionEvent.ACTION_DOWN, SOURCE_TOUCHSCREEN)
+                .pointer(new PointerBuilder(0, MotionEvent.TOOL_TYPE_FINGER)
+                        .x(initialX)
+                        .y(initialY)
+                )
+                .build();
+        mTouchpadDebugView.dispatchTouchEvent(actionDown);
+
+        MotionEvent actionMove = new MotionEventBuilder(MotionEvent.ACTION_MOVE, SOURCE_TOUCHSCREEN)
+                .pointer(new PointerBuilder(0, MotionEvent.TOOL_TYPE_FINGER)
+                        .x(initialX + offsetX)
+                        .y(initialY + offsetY)
+                )
+                .build();
+        mTouchpadDebugView.dispatchTouchEvent(actionMove);
+
+        MotionEvent actionUp = new MotionEventBuilder(MotionEvent.ACTION_UP, SOURCE_TOUCHSCREEN)
+                .pointer(new PointerBuilder(0, MotionEvent.TOOL_TYPE_FINGER)
+                        .x(initialX)
+                        .y(initialY)
+                )
+                .build();
+        mTouchpadDebugView.dispatchTouchEvent(actionUp);
+
+        // In this case the updateViewLayout() method wouldn't be called because the drag
+        // distance hasn't exceeded the slop
+        verify(mWindowManager, times(0)).updateViewLayout(any(), any());
+    }
+
+    @Test
+    public void testViewReturnsToInitialPositionOnCancel() {
+        int initialX = mWindowLayoutParams.x;
+        int initialY = mWindowLayoutParams.y;
+
+        float offsetX = 50;
+        float offsetY = 50;
+
+        MotionEvent actionDown = new MotionEventBuilder(MotionEvent.ACTION_DOWN, SOURCE_TOUCHSCREEN)
+                .pointer(new PointerBuilder(0, MotionEvent.TOOL_TYPE_FINGER)
+                        .x(initialX)
+                        .y(initialY)
+                )
+                .build();
+        mTouchpadDebugView.dispatchTouchEvent(actionDown);
+
+        MotionEvent actionMove = new MotionEventBuilder(MotionEvent.ACTION_MOVE, SOURCE_TOUCHSCREEN)
+                .pointer(new PointerBuilder(0, MotionEvent.TOOL_TYPE_FINGER)
+                        .x(initialX + offsetX)
+                        .y(initialY + offsetY)
+                )
+                .build();
+        mTouchpadDebugView.dispatchTouchEvent(actionMove);
+
+        ArgumentCaptor<WindowManager.LayoutParams> mWindowLayoutParamsCaptor =
+                ArgumentCaptor.forClass(WindowManager.LayoutParams.class);
+        verify(mWindowManager).updateViewLayout(any(), mWindowLayoutParamsCaptor.capture());
+
+        assertEquals(initialX + (long) offsetX, mWindowLayoutParamsCaptor.getValue().x);
+        assertEquals(initialY + (long) offsetY, mWindowLayoutParamsCaptor.getValue().y);
+
+        // Simulate ACTION_CANCEL event (canceling the touch event stream)
+        MotionEvent actionCancel = new MotionEventBuilder(MotionEvent.ACTION_CANCEL,
+                SOURCE_TOUCHSCREEN)
+                .pointer(new PointerBuilder(0, MotionEvent.TOOL_TYPE_FINGER)
+                        .x(initialX + offsetX)
+                        .y(initialY + offsetY)
+                )
+                .build();
+        mTouchpadDebugView.dispatchTouchEvent(actionCancel);
+
+        // Verify the view returns to its initial position
+        verify(mWindowManager, times(2)).updateViewLayout(any(),
+                mWindowLayoutParamsCaptor.capture());
+        assertEquals(initialX, mWindowLayoutParamsCaptor.getValue().x);
+        assertEquals(initialY, mWindowLayoutParamsCaptor.getValue().y);
+    }
+}
diff --git a/tests/TrustTests/Android.bp b/tests/TrustTests/Android.bp
index 4e75a1d..8888b32 100644
--- a/tests/TrustTests/Android.bp
+++ b/tests/TrustTests/Android.bp
@@ -40,3 +40,10 @@
     platform_apis: true,
     certificate: "platform",
 }
+
+test_module_config {
+    name: "TrustTests_trust_test",
+    base: "TrustTests",
+    test_suites: ["device-tests"],
+    include_filters: ["android.trust.test"],
+}